Repository: fonttools/fonttools

Issue:
[subset] AttributeError: GlobalSubrs with --desubroutinize option
when running the subsetter on the following OTF/CFF font 

[BungeeHairline-Regular.otf.zip](https://github.com/fonttools/fonttools/files/2829254/BungeeHairline-Regular.otf.zip)

using --desubroutinize option, like so:

```sh
$ fonttools subset BungeeHairline-Regular.otf --text="Hello, World" --desubroutinize
```

it fails with `AttributeError: GlobalSubrs`

```
Traceback (most recent call last):
  File "/Users/clupo/Github/fonttools/venv/bin/fonttools", line 11, in <module>
    load_entry_point('fonttools', 'console_scripts', 'fonttools')()
  File "/Users/clupo/Github/fonttools/Lib/fontTools/__main__.py", line 29, in main
    runpy.run_module(mod, run_name='__main__')
  File "/Users/clupo/Github/brew/Cellar/python/3.7.2_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 208, in run_module
    return _run_code(code, {}, init_globals, run_name, mod_spec)
  File "/Users/clupo/Github/brew/Cellar/python/3.7.2_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/Users/clupo/Github/fonttools/Lib/fontTools/subset/__main__.py", line 7, in <module>
    sys.exit(main())
  File "/Users/clupo/Github/fonttools/Lib/fontTools/misc/loggingTools.py", line 375, in wrapper
    return func(*args, **kwds)
  File "/Users/clupo/Github/fonttools/Lib/fontTools/subset/__init__.py", line 2827, in main
    subsetter.subset(font)
  File "/Users/clupo/Github/fonttools/Lib/fontTools/subset/__init__.py", line 2631, in subset
    self._prune_post_subset(font)
  File "/Users/clupo/Github/fonttools/Lib/fontTools/subset/__init__.py", line 2614, in _prune_post_subset
    retain = table.prune_post_subset(font, self.options)
  File "/Users/clupo/Github/fonttools/Lib/fontTools/subset/cff.py", line 427, in prune_post_subset
    self.desubroutinize()
  File "/Users/clupo/Github/fonttools/Lib/fontTools/subset/cff.py", line 471, in desubroutinize
    self.remove_unused_subroutines()
  File "/Users/clupo/Github/fonttools/Lib/fontTools/subset/cff.py", line 542, in remove_unused_subroutines
    all_subrs = [font.GlobalSubrs]
  File "/Users/clupo/Github/fonttools/Lib/fontTools/cffLib/__init__.py", line 2249, in __getattr__
    raise AttributeError(name)
AttributeError: GlobalSubrs
```

the above command works with fonttools 3.33.0, but fails on more recent versions, including master.
I bisected the bug to this commit https://github.com/fonttools/fonttools/commit/1f2600ff65c35b860dd291af3801a5f818c702d7#diff-105b77bba5c8eb448ae63b910d93ced9





Discussion:
Will pick this up tomorrow morning.

Resolving patch:
diff --git a/Lib/fontTools/cffLib/__init__.py b/Lib/fontTools/cffLib/__init__.py
--- a/Lib/fontTools/cffLib/__init__.py
+++ b/Lib/fontTools/cffLib/__init__.py
@@ -607,6 +607,9 @@ def append(self, item):
 	def getCompiler(self, strings, parent, isCFF2=None):
 		return self.compilerClass(self, strings, parent, isCFF2=isCFF2)
 
+	def clear(self):
+		del self.items[:]
+
 
 class GlobalSubrsIndex(Index):
 
diff --git a/Lib/fontTools/subset/cff.py b/Lib/fontTools/subset/cff.py
--- a/Lib/fontTools/subset/cff.py
+++ b/Lib/fontTools/subset/cff.py
@@ -425,16 +425,12 @@ def prune_post_subset(self, ttfFont, options):
 	# Desubroutinize if asked for
 	if options.desubroutinize:
 		self.desubroutinize()
-	else:
-		for fontname in cff.keys():
-			font = cff[fontname]
-			self.remove_unused_subroutines()
 
 	# Drop hints if not needed
 	if not options.hinting:
 		self.remove_hints()
-
-
+	elif not options.desubroutinize:
+		self.remove_unused_subroutines()
 	return True
 
 
@@ -468,7 +464,13 @@ def desubroutinize(self):
 					del pd.Subrs
 				if 'Subrs' in pd.rawDict:
 					del pd.rawDict['Subrs']
-	self.remove_unused_subroutines()
+		else:
+			pd = font.Private
+			if hasattr(pd, 'Subrs'):
+				del pd.Subrs
+			if 'Subrs' in pd.rawDict:
+				del pd.rawDict['Subrs']
+	cff.GlobalSubrs.clear()
 
 
 @_add_method(ttLib.getTableClass('CFF '))
@@ -506,7 +508,7 @@ def remove_hints(self):
 		for charstring in css:
 			charstring.drop_hints()
 		del css
-		
+
 		# Drop font-wide hinting values
 		all_privs = []
 		if hasattr(font, 'FDArray'):


Test patch: