Skip to content

Commit 7092294

Browse files
committed
Make code DRYer, and make it possible for this to work under Py2 and Py3.
1 parent 84412cf commit 7092294

File tree

5 files changed

+41
-53
lines changed

5 files changed

+41
-53
lines changed

html5lib/treebuilders/dom.py

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,12 @@
11

22
from xml.dom import minidom, Node, XML_NAMESPACE, XMLNS_NAMESPACE
3-
try:
4-
from types import ModuleType
5-
except:
6-
from new import module as ModuleType
73
import re
84
import weakref
95

106
from . import _base
117
from html5lib import constants, ihatexml
128
from html5lib.constants import namespaces
13-
14-
moduleCache = {}
15-
16-
def getDomModule(DomImplementation):
17-
name = "_" + DomImplementation.__name__+"builder"
18-
if name in moduleCache:
19-
return moduleCache[name]
20-
else:
21-
mod = ModuleType(name)
22-
objs = getDomBuilder(DomImplementation)
23-
mod.__dict__.update(objs)
24-
moduleCache[name] = mod
25-
return mod
9+
from html5lib.utils import moduleFactoryFactory
2610

2711
def getDomBuilder(DomImplementation):
2812
Dom = DomImplementation
@@ -285,6 +269,11 @@ def dom2sax(node, handler, nsmap={'xml':XML_NAMESPACE}):
285269

286270
return locals()
287271

272+
273+
# The actual means to get a module!
274+
getDomModule = moduleFactoryFactory(getDomBuilder)
275+
276+
288277
# Keep backwards compatibility with things that directly load
289278
# classes/functions from this module
290279
for key, value in list(getDomModule(minidom).__dict__.items()):

html5lib/treebuilders/etree.py

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,13 @@
1-
try:
2-
from types import ModuleType
3-
except:
4-
from new import module as ModuleType
51
import re
6-
import types
72

83
from . import _base
94
from html5lib import ihatexml
105
from html5lib import constants
116
from html5lib.constants import namespaces
7+
from html5lib.utils import moduleFactoryFactory
128

139
tag_regexp = re.compile("{([^}]*)}(.*)")
1410

15-
moduleCache = {}
16-
17-
def getETreeModule(ElementTreeImplementation, fullTree=False):
18-
name = "_" + ElementTreeImplementation.__name__+"builder"
19-
if name in moduleCache:
20-
return moduleCache[name]
21-
else:
22-
mod = ModuleType("_" + ElementTreeImplementation.__name__+"builder")
23-
objs = getETreeBuilder(ElementTreeImplementation, fullTree)
24-
mod.__dict__.update(objs)
25-
moduleCache[name] = mod
26-
return mod
27-
2811
def getETreeBuilder(ElementTreeImplementation, fullTree=False):
2912
ElementTree = ElementTreeImplementation
3013
class Element(_base.Node):
@@ -342,3 +325,6 @@ def getFragment(self):
342325
return _base.TreeBuilder.getFragment(self)._element
343326

344327
return locals()
328+
329+
330+
getETreeModule = moduleFactoryFactory(getETreeBuilder)

html5lib/treewalkers/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
returning an iterator generating tokens.
99
"""
1010

11+
from importlib import import_module
12+
1113
treeWalkerCache = {}
1214

1315
def getTreeWalker(treeType, implementation=None, **kwargs):
@@ -34,7 +36,7 @@ def getTreeWalker(treeType, implementation=None, **kwargs):
3436
treeType = treeType.lower()
3537
if treeType not in treeWalkerCache:
3638
if treeType in ("dom", "pulldom", "simpletree"):
37-
mod = __import__(treeType, globals())
39+
mod = import_module("."+treeType, "html5lib.treewalkers")
3840
treeWalkerCache[treeType] = mod.TreeWalker
3941
elif treeType == "genshi":
4042
from . import genshistream

html5lib/treewalkers/etree.py

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,15 @@
11
import gettext
22
_ = gettext.gettext
33

4-
try:
5-
from types import ModuleType
6-
except:
7-
from new import module as ModuleType
84
import copy
95
import re
106

117
from . import _base
128
from html5lib.constants import voidElements
9+
from html5lib.utils import moduleFactorFactory
1310

1411
tag_regexp = re.compile("{([^}]*)}(.*)")
1512

16-
moduleCache = {}
17-
18-
def getETreeModule(ElementTreeImplementation):
19-
name = "_" + ElementTreeImplementation.__name__+"builder"
20-
if name in moduleCache:
21-
return moduleCache[name]
22-
else:
23-
mod = ModuleType("_" + ElementTreeImplementation.__name__+"builder")
24-
objs = getETreeBuilder(ElementTreeImplementation)
25-
mod.__dict__.update(objs)
26-
moduleCache[name] = mod
27-
return mod
28-
2913
def getETreeBuilder(ElementTreeImplementation):
3014
ElementTree = ElementTreeImplementation
3115

@@ -139,3 +123,5 @@ def getParentNode(self, node):
139123
return parent, list(parents[-1]).index(parent), parents, None
140124

141125
return locals()
126+
127+
getETreeModule = moduleFactoryFactory(getETreeBuilder)

html5lib/utils.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
from sets import Set as set
66
from sets import ImmutableSet as frozenset
77

8+
from types import ModuleType
9+
10+
811
class MethodDispatcher(dict):
912
"""Dict with 2 special properties:
1013
@@ -173,3 +176,25 @@ def surrogatePairToCodepoint(data):
173176
char_val = (0x10000 + (ord(data[0]) - 0xD800) * 0x400 +
174177
(ord(data[1]) - 0xDC00))
175178
return char_val
179+
180+
# Module Factory Factory (no, this isn't Java, I know)
181+
# Here to stop this being duplicated all over the place.
182+
183+
def moduleFactoryFactory(factory):
184+
moduleCache = {}
185+
def moduleFactory(baseModule, *args, **kwargs):
186+
if type(ModuleType.__name__) is str:
187+
name = "_%s_factory" % baseModule.__name__
188+
else:
189+
name = b"_%s_factory" % baseModule.__name__
190+
191+
if name in moduleCache:
192+
return moduleCache[name]
193+
else:
194+
mod = ModuleType(name)
195+
objs = factory(baseModule, *args, **kwargs)
196+
mod.__dict__.update(objs)
197+
moduleCache[name] = mod
198+
return mod
199+
200+
return moduleFactory

0 commit comments

Comments
 (0)