bug 1368026, rename observers to observers and stat_observers, r=stas
authorAxel Hecht <axel@pike.org>
Fri, 26 May 2017 15:34:01 +0200
changeset 243 44f0db5abfab2873c8f17d8868647016d126283a
parent 240 34d99a0dd563d4939b8c9e13fc60591e24243014
child 244 69c2d3bc1d46bf0040a23ed6b31a4c804ac28c41
child 245 8b6af885adb94191f241f2c75a0edb8927bc20bb
push id51
push useraxel@mozilla.com
push dateFri, 26 May 2017 16:52:32 +0000
reviewersstas
bugs1368026
bug 1368026, rename observers to observers and stat_observers, r=stas The `observers` name is now internal to ContentComparer, and passed in as unconditional list argument to the constructor. What used to be other_observers is now stat_observers, and an optional keyword argument. MozReview-Commit-ID: LN5dCAKKvN3
compare_locales/commands.py
compare_locales/compare.py
compare_locales/tests/test_merge.py
--- a/compare_locales/commands.py
+++ b/compare_locales/commands.py
@@ -121,16 +121,16 @@ Be careful to specify the right merge di
             app = EnumerateApp(config_path, args.l10n_base_dir, args.locales)
             configs.append(app.asConfig())
         try:
             unified_observer = None
             if args.unified:
                 unified_observer = Observer()
             observers = compareProjects(
                 configs,
-                other_observer=unified_observer,
+                stat_observer=unified_observer,
                 merge_stage=args.merge, clobber_merge=args.clobber)
         except (OSError, IOError), exc:
             print "FAIL: " + str(exc)
             self.parser.exit(2)
         if args.unified:
             return [unified_observer]
         return observers
--- a/compare_locales/compare.py
+++ b/compare_locales/compare.py
@@ -147,20 +147,20 @@ class AddRemove(SequenceMatcher):
                 for item in self.b[j1:j2]:
                     yield ('add', item)
 
 
 class Observer(object):
     stat_cats = ['missing', 'obsolete', 'missingInFiles', 'report',
                  'changed', 'unchanged', 'keys']
 
-    def __init__(self, file_stats=False):
+    def __init__(self, filter=None, file_stats=False):
         self.summary = defaultdict(lambda: defaultdict(int))
         self.details = Tree(dict)
-        self.filter = None
+        self.filter = filter
         self.file_stats = None
         if file_stats:
             self.file_stats = defaultdict(lambda: defaultdict(dict))
 
     # support pickling
     def __getstate__(self):
         state = dict(summary=self._dictify(self.summary), details=self.details)
         if self.file_stats is not None:
@@ -345,32 +345,28 @@ class Observer(object):
     def __str__(self):
         return 'observer'
 
 
 class ContentComparer:
     keyRE = re.compile('[kK]ey')
     nl = re.compile('\n', re.M)
 
-    def __init__(self):
+    def __init__(self, observers, stat_observers=None):
         '''Create a ContentComparer.
         observer is usually a instance of Observer. The return values
         of the notify method are used to control the handling of missing
         entities.
         '''
-        self.observers = []
-        self.other_observers = []
+        self.observers = observers
+        if stat_observers is None:
+            stat_observers = []
+        self.stat_observers = stat_observers
         self.merge_stage = None
 
-    def add_observer(self, obs):
-        '''Add a non-filtering observer.
-        Results from the notify calls are ignored.
-        '''
-        self.other_observers.append(obs)
-
     def set_merge_stage(self, merge_stage):
         self.merge_stage = merge_stage
 
     def merge(self, ref_entities, ref_map, ref_file, l10n_file, missing,
               skips, ctx, canMerge, encoding):
         outfile = mozpath.join(self.merge_stage, l10n_file.module,
                                l10n_file.file)
         outdir = mozpath.dirname(outfile)
@@ -406,38 +402,38 @@ class ContentComparer:
                 return s + '\n'
             return s
 
         f.write(''.join(map(ensureNewline, trailing)))
         f.close()
 
     def notify(self, category, file, data):
         """Check observer for the found data, and if it's
-        not to ignore, notify other_observers.
+        not to ignore, notify stat_observers.
         """
         rvs = set(
             observer.notify(category, file, data)
             for observer in self.observers
             )
         if all(rv == 'ignore' for rv in rvs):
             return 'ignore'
         rvs.discard('ignore')
-        for obs in self.other_observers:
-            # non-filtering other_observers, ignore results
+        for obs in self.stat_observers:
+            # non-filtering stat_observers, ignore results
             obs.notify(category, file, data)
         if 'error' in rvs:
             return 'error'
         assert len(rvs) == 1
         return rvs.pop()
 
     def updateStats(self, file, stats):
         """Check observer for the found data, and if it's
-        not to ignore, notify other_observers.
+        not to ignore, notify stat_observers.
         """
-        for observer in self.observers + self.other_observers:
+        for observer in self.observers + self.stat_observers:
             observer.updateStats(file, stats)
 
     def remove(self, obsolete):
         self.notify('obsoleteFile', obsolete, None)
         pass
 
     def compare(self, ref_file, l10n, extra_tests=None):
         try:
@@ -573,28 +569,30 @@ class ContentComparer:
         # overload this if needed
         pass
 
     def doChanged(self, file, ref_entity, l10n_entity):
         # overload this if needed
         pass
 
 
-def compareProjects(project_configs, other_observer=None,
+def compareProjects(project_configs, stat_observer=None,
                     file_stats=False,
                     merge_stage=None, clobber_merge=False):
-    comparer = ContentComparer()
-    if other_observer is not None:
-        comparer.add_observer(other_observer)
     locales = set()
+    observers = []
     for project in project_configs:
-        observer = Observer(file_stats=file_stats)
-        observer.filter = project.filter
-        comparer.observers.append(observer)
+        observers.append(
+            Observer(filter=project.filter, file_stats=file_stats))
         locales.update(project.locales)
+    if stat_observer is not None:
+        stat_observers = [stat_observer]
+    else:
+        stat_observers = None
+    comparer = ContentComparer(observers, stat_observers=stat_observers)
     for locale in sorted(locales):
         files = paths.ProjectFiles(locale, *project_configs)
         if merge_stage is not None:
             mergedir = merge_stage.format(ab_CD=locale)
             comparer.set_merge_stage(mergedir)
             if clobber_merge:
                 modules = set(_m.get('module') for _m in files.matchers)
                 modules.discard(None)
@@ -616,9 +614,9 @@ def compareProjects(project_configs, oth
                               module=module, locale=locale)
             if not os.path.exists(l10npath):
                 comparer.add(reffile, l10n)
                 continue
             if not os.path.exists(refpath):
                 comparer.remove(l10n)
                 continue
             comparer.compare(reffile, l10n, extra_tests)
-    return comparer.observers
+    return observers
--- a/compare_locales/tests/test_merge.py
+++ b/compare_locales/tests/test_merge.py
@@ -41,18 +41,17 @@ class TestProperties(unittest.TestCase, 
         self.assertTrue(os.path.isdir(self.tmp))
         self.reference("""foo = fooVal
 bar = barVal
 eff = effVal""")
         self.localized("""foo = lFoo
 bar = lBar
 eff = lEff
 """)
-        cc = ContentComparer()
-        cc.observers.append(Observer())
+        cc = ContentComparer([Observer()])
         cc.set_merge_stage(mozpath.join(self.tmp, "merge"))
         cc.compare(File(self.ref, "en-reference.properties", ""),
                    File(self.l10n, "l10n.properties", ""))
         self.assertDictEqual(
             cc.observers[0].toJSON(),
             {'summary':
                 {None: {
                     'changed': 3
@@ -65,18 +64,17 @@ eff = lEff
 
     def testMissing(self):
         self.assertTrue(os.path.isdir(self.tmp))
         self.reference("""foo = fooVal
 bar = barVal
 eff = effVal""")
         self.localized("""bar = lBar
 """)
-        cc = ContentComparer()
-        cc.observers.append(Observer())
+        cc = ContentComparer([Observer()])
         cc.set_merge_stage(mozpath.join(self.tmp, "merge"))
         cc.compare(File(self.ref, "en-reference.properties", ""),
                    File(self.l10n, "l10n.properties", ""))
         self.assertDictEqual(
             cc.observers[0].toJSON(),
             {'summary':
                 {None: {
                     'changed': 1, 'missing': 2
@@ -100,18 +98,17 @@ eff = effVal""")
         self.assertTrue(os.path.isdir(self.tmp))
         self.reference("""foo = fooVal
 bar = %d barVal
 eff = effVal""")
         self.localized("""\
 bar = %S lBar
 eff = leffVal
 """)
-        cc = ContentComparer()
-        cc.observers.append(Observer())
+        cc = ContentComparer([Observer()])
         cc.set_merge_stage(mozpath.join(self.tmp, "merge"))
         cc.compare(File(self.ref, "en-reference.properties", ""),
                    File(self.l10n, "l10n.properties", ""))
         self.assertDictEqual(
             cc.observers[0].toJSON(),
             {'summary':
                 {None: {
                     'changed': 2, 'errors': 1, 'missing': 1
@@ -138,18 +135,17 @@ eff = leffVal
     def testObsolete(self):
         self.assertTrue(os.path.isdir(self.tmp))
         self.reference("""foo = fooVal
 eff = effVal""")
         self.localized("""foo = fooVal
 other = obsolete
 eff = leffVal
 """)
-        cc = ContentComparer()
-        cc.observers.append(Observer())
+        cc = ContentComparer([Observer()])
         cc.set_merge_stage(mozpath.join(self.tmp, "merge"))
         cc.compare(File(self.ref, "en-reference.properties", ""),
                    File(self.l10n, "l10n.properties", ""))
         self.assertDictEqual(
             cc.observers[0].toJSON(),
             {'summary':
                 {None: {
                     'changed': 1, 'obsolete': 1, 'unchanged': 1
@@ -178,18 +174,17 @@ class TestDTD(unittest.TestCase, Content
         self.assertTrue(os.path.isdir(self.tmp))
         self.reference("""<!ENTITY foo 'fooVal'>
 <!ENTITY bar 'barVal'>
 <!ENTITY eff 'effVal'>""")
         self.localized("""<!ENTITY foo 'lFoo'>
 <!ENTITY bar 'lBar'>
 <!ENTITY eff 'lEff'>
 """)
-        cc = ContentComparer()
-        cc.observers.append(Observer())
+        cc = ContentComparer([Observer()])
         cc.set_merge_stage(mozpath.join(self.tmp, "merge"))
         cc.compare(File(self.ref, "en-reference.dtd", ""),
                    File(self.l10n, "l10n.dtd", ""))
         self.assertDictEqual(
             cc.observers[0].toJSON(),
             {'summary':
                 {None: {
                     'changed': 3
@@ -202,18 +197,17 @@ class TestDTD(unittest.TestCase, Content
 
     def testMissing(self):
         self.assertTrue(os.path.isdir(self.tmp))
         self.reference("""<!ENTITY foo 'fooVal'>
 <!ENTITY bar 'barVal'>
 <!ENTITY eff 'effVal'>""")
         self.localized("""<!ENTITY bar 'lBar'>
 """)
-        cc = ContentComparer()
-        cc.observers.append(Observer())
+        cc = ContentComparer([Observer()])
         cc.set_merge_stage(mozpath.join(self.tmp, "merge"))
         cc.compare(File(self.ref, "en-reference.dtd", ""),
                    File(self.l10n, "l10n.dtd", ""))
         self.assertDictEqual(
             cc.observers[0].toJSON(),
             {'summary':
                 {None: {
                     'changed': 1, 'missing': 2
@@ -237,18 +231,17 @@ class TestDTD(unittest.TestCase, Content
         self.assertTrue(os.path.isdir(self.tmp))
         self.reference("""<!ENTITY foo 'fooVal'>
 <!ENTITY bar 'barVal'>
 <!ENTITY eff 'effVal'>""")
         self.localized("""<!ENTITY foo 'fooVal'>
 <!ENTY bar 'gimmick'>
 <!ENTITY eff 'effVal'>
 """)
-        cc = ContentComparer()
-        cc.observers.append(Observer())
+        cc = ContentComparer([Observer()])
         cc.set_merge_stage(mozpath.join(self.tmp, "merge"))
         cc.compare(File(self.ref, "en-reference.dtd", ""),
                    File(self.l10n, "l10n.dtd", ""))
         self.assertDictEqual(
             cc.observers[0].toJSON(),
             {'summary':
                 {None: {
                     'errors': 1, 'missing': 1, 'unchanged': 2