From e3dbe68b49e29317a24164a602732b0e9db9612d Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Wed, 11 Nov 2020 14:41:44 -0800 Subject: [PATCH 1/2] Allow passing iterator flags into GetPropertyValues --- etg/propgridiface.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/etg/propgridiface.py b/etg/propgridiface.py index 402b6ba6..4f020b21 100644 --- a/etg/propgridiface.py +++ b/etg/propgridiface.py @@ -215,18 +215,20 @@ def run(): c.find('GetPropertyValues').ignore() c.addPyMethod('GetPropertyValues', - '(self, dict_=None, as_strings=False, inc_attributes=False)', + '(self, dict_=None, as_strings=False, inc_attributes=False, flags=PG_ITERATE_PROPERTIES)', doc="""\ - Returns all property values in the grid.\n - :param `dict_`: A to fill with the property values. If not given, - then a new one is created. The dict_ can be an object as well, - in which case it's __dict__ is used. + Returns all property values in the grid. + + :param `dict_`: A diftionary to fill with the property values. + If not given, then a new one is created. The dict_ can be an + object as well, in which case it's __dict__ is used. :param `as_strings`: if True, then string representations of values are fetched instead of native types. Useful for config and such. :param `inc_attributes`: if True, then property attributes are added - in the form of "@@". + in the form of ``"@@"``. + :param `flags`: Flags to pass to the iterator, see :ref:`wx.propgrid.PG_ITERATOR_FLAGS` :returns: A dictionary with values. It is always a dictionary, - so if dict_ was and object with __dict__ attribute, then that + so if dict_ was an object with __dict__ attribute, then that attribute is returned. """, body="""\ @@ -237,7 +239,7 @@ def run(): getter = self.GetPropertyValue if not as_strings else self.GetPropertyValueAsString - it = self.GetVIterator(PG_ITERATE_PROPERTIES) + it = self.GetVIterator(flags) while not it.AtEnd(): p = it.GetProperty() name = p.GetName() @@ -314,7 +316,7 @@ def run(): self.Refresh() """) - # TODO: should these be marked as deprecated? + # TODO: should these be marked as deprecated? Probably... module.addPyCode("""\ PropertyGridInterface.GetValues = PropertyGridInterface.GetPropertyValues PropertyGridInterface.SetValues = PropertyGridInterface.SetPropertyValues From 7a839de24872c7feb95471aceafabcb49416e7a9 Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Wed, 11 Nov 2020 15:40:05 -0800 Subject: [PATCH 2/2] Make it possible to call a function that post-processes the generated ReST doc for a class. --- etg/propgridiface.py | 10 +++++++++- etgtools/extractors.py | 6 ++++++ etgtools/sphinx_generator.py | 9 +++++++++ sphinxtools/utilities.py | 16 +++++++++++++++- 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/etg/propgridiface.py b/etg/propgridiface.py index 4f020b21..9425f84e 100644 --- a/etg/propgridiface.py +++ b/etg/propgridiface.py @@ -226,7 +226,7 @@ def run(): are fetched instead of native types. Useful for config and such. :param `inc_attributes`: if True, then property attributes are added in the form of ``"@@"``. - :param `flags`: Flags to pass to the iterator, see :ref:`wx.propgrid.PG_ITERATOR_FLAGS` + :param `flags`: Flags to pass to the iterator. See :ref:`wx.propgrid.PG_ITERATOR_FLAGS`. :returns: A dictionary with values. It is always a dictionary, so if dict_ was an object with __dict__ attribute, then that attribute is returned. @@ -505,6 +505,14 @@ def run(): c.addPyProperty('Items', '_Items') + def postProcessReST(text): + # fix some autodoc glitches + text = text.replace(':ref:`PropertyGridIterator Flags `', + ':ref:`wx.propgrid.PG_ITERATOR_FLAGS`') + return text + + c.setReSTPostProcessor(postProcessReST) + #---------------------------------------------------------- module.addItem( diff --git a/etgtools/extractors.py b/etgtools/extractors.py index 757ec61b..8c992cb1 100644 --- a/etgtools/extractors.py +++ b/etgtools/extractors.py @@ -684,6 +684,7 @@ class ClassDef(BaseDef): self.isInner = False # Is this a nested class? self.klass = None # if so, then this is the outer class self.preMethodCode = None + self.postProcessReST = None # Stuff that needs to be generated after the class instead of within # it. Some back-end generators need to put stuff inside the class, and @@ -1157,6 +1158,11 @@ private: self.addItem(item) return item + def setReSTPostProcessor(self, func): + """ + Set a function to be called after the class's docs have been generated. + """ + self.postProcessReST = func #--------------------------------------------------------------------------- diff --git a/etgtools/sphinx_generator.py b/etgtools/sphinx_generator.py index 1897ab25..8ecd2165 100644 --- a/etgtools/sphinx_generator.py +++ b/etgtools/sphinx_generator.py @@ -48,6 +48,7 @@ from sphinxtools.utilities import pickleClassInfo, pickleFunctionInfo, isNumeric from sphinxtools.utilities import underscore2Capitals, countSpaces from sphinxtools.utilities import formatContributedSnippets from sphinxtools.utilities import PickleFile +from sphinxtools.utilities import textfile_open from sphinxtools.constants import VERSION, REMOVED_LINKS, SECTIONS from sphinxtools.constants import MAGIC_METHODS, MODULENAME_REPLACE @@ -3230,6 +3231,14 @@ class SphinxGenerator(generators.DocsGeneratorBase): f = dispatch[item.__class__][0] f(item) + if klass.postProcessReST is not None: + full_name = os.path.join(SPHINXROOT, filename) + with textfile_open(full_name) as f: + text = f.read() + text = klass.postProcessReST(text) + with textfile_open(full_name, 'wt') as f: + f.write(text) + if klass.enum_list: stream = StringIO() stream.write("\n.. toctree::\n :maxdepth: 1\n :hidden:\n\n") diff --git a/sphinxtools/utilities.py b/sphinxtools/utilities.py index 6177a10a..662d5275 100644 --- a/sphinxtools/utilities.py +++ b/sphinxtools/utilities.py @@ -561,7 +561,7 @@ header = """\ This file was generated by Phoenix's sphinx generator and associated tools, do not edit by hand. - Copyright: (c) 2011-2018 by Total Control Software + Copyright: (c) 2011-2020 by Total Control Software License: wxWindows License """ @@ -861,3 +861,17 @@ def isPython3(): return sys.version_info >= (3, ) + +def textfile_open(filename, mode='rt'): + """ + Simple wrapper around open() that will use codecs.open on Python2 and + on Python3 will add the encoding parameter to the normal open(). The + mode parameter must include the 't' to put the stream into text mode. + """ + assert 't' in mode + if sys.version_info < (3,): + import codecs + mode = mode.replace('t', '') + return codecs.open(filename, mode, encoding='utf-8') + else: + return open(filename, mode, encoding='utf-8')