From 4e7a6e9bc20f392ce6f9a2bf512e4edc4df159c2 Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 15:46:45 -0500 Subject: [PATCH 01/26] tests: remove legacy python file coding Removing legacy Python file encoding from sample Python files. They are not needed for the specific testing or examples, and best to avoid their promotion in our example. Removing also prevents ruff warnings on their detection. Signed-off-by: James Knight --- tests/unit-tests/assets/example.py | 2 -- tests/validation-sets/sphinx/assets/example.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/tests/unit-tests/assets/example.py b/tests/unit-tests/assets/example.py index 7b325982..dfce4cab 100644 --- a/tests/unit-tests/assets/example.py +++ b/tests/unit-tests/assets/example.py @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - import sys diff --git a/tests/validation-sets/sphinx/assets/example.py b/tests/validation-sets/sphinx/assets/example.py index 93e9bd1d..75d9766d 100644 --- a/tests/validation-sets/sphinx/assets/example.py +++ b/tests/validation-sets/sphinx/assets/example.py @@ -1,3 +1 @@ -# -*- coding: utf-8 -*- - print('hello world') From 075decbbfb9c5c60d9b4c2bb354f678e7f7dedf7 Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 15:53:58 -0500 Subject: [PATCH 02/26] refactor define processing from a mainline Tweaking the processing of accepting defines from a command line argument by: - Moving the value error process outside the defines loop for performance (PERF203). - Adjusting the define loop to be a bit more explicit between a define entry and a define's value. Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/cmd/build.py | 12 ++++++------ tests/test_sample.py | 12 ++++++------ tests/test_sandbox.py | 12 ++++++------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/cmd/build.py b/sphinxcontrib/confluencebuilder/cmd/build.py index 8aba544a..a96cfee6 100644 --- a/sphinxcontrib/confluencebuilder/cmd/build.py +++ b/sphinxcontrib/confluencebuilder/cmd/build.py @@ -34,13 +34,13 @@ def build_main(args_parser): logger.warn('unknown arguments: {}'.format(' '.join(unknown_args))) defines = {} - for val in args.define: - try: - key, val = val.split('=', 1) + try: + for define in args.define: + key, val = define.split('=', 1) defines[key] = val - except ValueError: - logger.error('invalid define provided in command line') - return 1 + except ValueError: + logger.error('invalid define provided in command line') + return 1 work_dir = args.work_dir if args.work_dir else Path.cwd() if args.output_dir: diff --git a/tests/test_sample.py b/tests/test_sample.py index 83a1a470..73fc339d 100644 --- a/tests/test_sample.py +++ b/tests/test_sample.py @@ -25,13 +25,13 @@ def main(): parser.parse_args() defines = {} - for val in args.define: - try: - key, val = val.split('=', 1) + try: + for define in args.define: + key, val = define.split('=', 1) defines[key] = val - except ValueError: - print('[sandbox] invalid define provided in command line') - return 1 + except ValueError: + print('[sandbox] invalid define provided in command line') + return 1 if args.debug or args.verbose: if 'SPHINX_VERBOSITY' not in os.environ: diff --git a/tests/test_sandbox.py b/tests/test_sandbox.py index 7d87ac55..126694ba 100644 --- a/tests/test_sandbox.py +++ b/tests/test_sandbox.py @@ -79,13 +79,13 @@ def main(): parser.parse_args() defines = {} - for val in args.define: - try: - key, val = val.split('=', 1) + try: + for define in args.define: + key, val = define.split('=', 1) defines[key] = val - except ValueError: - print('[sandbox] invalid define provided in command line') - return 1 + except ValueError: + print('[sandbox] invalid define provided in command line') + return 1 print('[sandbox] target sandbox:', args.sandbox) From f2ea99331ad8a6e959e2cf01dd0effe25a318a2c Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 16:06:22 -0500 Subject: [PATCH 03/26] tests: update expected line-count with test asset change Since a test asset's line length has been changed [1], the unit test using this asset also needs to be updated. [1]: 4e7a6e9bc20f392ce6f9a2bf512e4edc4df159c2 Signed-off-by: James Knight --- tests/unit-tests/test_rst_literal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit-tests/test_rst_literal.py b/tests/unit-tests/test_rst_literal.py index b385c620..fbba8fda 100644 --- a/tests/unit-tests/test_rst_literal.py +++ b/tests/unit-tests/test_rst_literal.py @@ -137,4 +137,4 @@ def test_storage_rst_literal_includes(self): firstline = block.find('ac:parameter', {'ac:name': 'firstline'}) self.assertIsNotNone(firstline) - self.assertEqual(firstline.text, '6') + self.assertEqual(firstline.text, '4') From 82bf0a68b3c082916310534ef86c3d1eabc30926 Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 16:18:21 -0500 Subject: [PATCH 04/26] builder: noqa on private member access of sphinx's writer doc cache Adding a noqa warning on using a Sphinx private member variable required for a workaround (at this time) for this extension's doctree manipulations. Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/builder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinxcontrib/confluencebuilder/builder.py b/sphinxcontrib/confluencebuilder/builder.py index cdaa1654..0f89011e 100644 --- a/sphinxcontrib/confluencebuilder/builder.py +++ b/sphinxcontrib/confluencebuilder/builder.py @@ -267,7 +267,7 @@ def prepare_writing(self, docnames): # environment is performing any doctree caching, clear the entire # cache if getattr(self.env, '_write_doc_doctree_cache', None): - self.env._write_doc_doctree_cache = {} + self.env._write_doc_doctree_cache = {} # noqa: SLF001 # process the document structure of the root document, populating a # publish order to ensure parent pages are created first (when using From 76a48d36a0590ad5726e4939825733e5807833ae Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 16:24:13 -0500 Subject: [PATCH 05/26] rework for-loops to ignore unused values Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/builder.py | 4 ++-- sphinxcontrib/confluencebuilder/storage/index.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/builder.py b/sphinxcontrib/confluencebuilder/builder.py index 0f89011e..f14f0bb6 100644 --- a/sphinxcontrib/confluencebuilder/builder.py +++ b/sphinxcontrib/confluencebuilder/builder.py @@ -374,7 +374,7 @@ def prepare_writing(self, docnames): labels['search'] = 'search', '', '' if self.domain_indices: - for indexname, _ in self.domain_indices.items(): + for indexname in self.domain_indices: anonlabels[indexname] = indexname, '' labels[indexname] = indexname, '', '' @@ -719,7 +719,7 @@ def finish(self): # build domain indexes if self.domain_indices: - for indexname, indexdata in self.domain_indices.items(): + for indexname in self.domain_indices: self.info(f'generating index ({indexname})...', nonl=(not self._verbose)) diff --git a/sphinxcontrib/confluencebuilder/storage/index.py b/sphinxcontrib/confluencebuilder/storage/index.py index 25431ce8..01872fba 100644 --- a/sphinxcontrib/confluencebuilder/storage/index.py +++ b/sphinxcontrib/confluencebuilder/storage/index.py @@ -29,7 +29,7 @@ def generate_storage_format_domainindex(builder, docname, f): return # pre-process link entries to use final document titles/anchor values - for key, entries in content: + for _, entries in content: for (i, entry) in enumerate(entries): if isinstance(entry, list): refuri = f'{entry[2]}#{entry[3]}' @@ -80,12 +80,12 @@ def generate_storage_format_genindex(builder, docname, f): return # pre-process link entries to use final document titles/anchor values - for key, columns in genindex: - for entryname, (links, subitems, key_) in columns: + for _, columns in genindex: + for _, (links, subitems, _) in columns: for (i, (ismain, link)) in enumerate(links): links[i] = ( ismain, process_doclink(builder.config, link)) - for subentryname, subentrylinks in subitems: + for _, subentrylinks in subitems: for (i, (ismain, link)) in enumerate(subentrylinks): subentrylinks[i] = ( ismain, process_doclink(builder.config, link)) From 018e635422a202e15f8dfdee973dc6cd57106d03 Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 16:33:44 -0500 Subject: [PATCH 06/26] implicitly concatenated string Update various messages defined over multiple lines to be implicitly concatenated string (ISC002). Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/directives.py | 36 +++++++---- sphinxcontrib/confluencebuilder/publisher.py | 61 ++++++++++++------- sphinxcontrib/confluencebuilder/state.py | 6 +- 3 files changed, 68 insertions(+), 35 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/directives.py b/sphinxcontrib/confluencebuilder/directives.py index f6385759..5d7df2e0 100644 --- a/sphinxcontrib/confluencebuilder/directives.py +++ b/sphinxcontrib/confluencebuilder/directives.py @@ -260,34 +260,46 @@ def run(self): # if explicit server is provided, ensure both options are set if 'server' in params or 'serverId' in params: if 'server' not in params: - msg = ':server-name: required when server-id is ' \ - 'set; but none supplied' + msg = ( + ':server-name: required when server-id is set; ' + 'but none supplied' + ) raise self.error(msg) if 'serverId' not in params: - msg = ':server-id: required when server-name is ' \ - 'set; but none supplied' + msg = ( + ':server-id: required when server-name is set; ' + 'but none supplied' + ) raise self.error(msg) # if a server key is provided, fetch values from configuration elif target_server: config = self.state.document.settings.env.config if not config.confluence_jira_servers: - msg = ':server: is set but no ' \ - 'confluence_jira_servers defined in config' + msg = ( + ':server: is set but no ' + 'confluence_jira_servers defined in config' + ) raise self.error(msg) jira_servers = config['confluence_jira_servers'] if target_server not in jira_servers: - msg = ':server: is set but does not exist in ' \ - 'confluence_jira_servers config' + msg = ( + ':server: is set but does not exist in ' + 'confluence_jira_servers config' + ) raise self.error(msg) jira_server_config = jira_servers[target_server] if 'name' not in jira_server_config: - msg = ':server: is set but missing name entry in ' \ - 'confluence_jira_servers config' + msg = ( + ':server: is set but missing name entry in ' + 'confluence_jira_servers config' + ) raise self.error(msg) params['server'] = jira_server_config['name'] if 'id' not in jira_server_config: - msg = ':server: is set but missing id entry in ' \ - 'confluence_jira_servers config' + msg = ( + ':server: is set but missing id entry in ' + 'confluence_jira_servers config' + ) raise self.error(msg) params['serverId'] = jira_server_config['id'] diff --git a/sphinxcontrib/confluencebuilder/publisher.py b/sphinxcontrib/confluencebuilder/publisher.py index 1372678e..05ba0bf1 100644 --- a/sphinxcontrib/confluencebuilder/publisher.py +++ b/sphinxcontrib/confluencebuilder/publisher.py @@ -89,8 +89,10 @@ def connect(self): detected_key = rsp['key'] if detected_key != self.space_key: - msg = 'server did not provide an expected response; ' \ - f'bad key match; {detected_key} != {self.space_key}' + msg = ( + 'server did not provide an expected response; ' + f'bad key match; {detected_key} != {self.space_key}' + ) raise ConfluenceBadServerUrlError(server_url, msg) # track required space information @@ -131,8 +133,10 @@ def archive_page(self, page_id): msg = 'timeout waiting for archive completion' raise ConfluenceBadApiError(-1, msg) except ConfluencePermissionError as ex: - msg = 'Publish user does not have permission to archive ' \ - 'from the configured space.' + msg = ( + 'Publish user does not have permission to archive ' + 'from the configured space.' + ) raise ConfluencePermissionError(msg) from ex def archive_pages(self, page_ids): @@ -157,8 +161,10 @@ def archive_pages(self, page_ids): self.rest_client.post('content/archive', data) except ConfluencePermissionError as ex: - msg = 'Publish user does not have permission to archive ' \ - 'from the configured space.' + msg = ( + 'Publish user does not have permission to archive ' + 'from the configured space.' + ) raise ConfluencePermissionError(msg) from ex def get_ancestors(self, page_id): @@ -693,8 +699,10 @@ def store_attachment(self, page_id, name, data, mimetype, hash_, force=False): self.rest_client.delete('user/watch/content', uploaded_attachment_id) except ConfluencePermissionError as ex: - msg = 'Publish user does not have permission to add an ' \ - 'attachment to the configured space.' + msg = ( + 'Publish user does not have permission to add an ' + 'attachment to the configured space.' + ) raise ConfluencePermissionError(msg) from ex return uploaded_attachment_id @@ -845,9 +853,10 @@ def store_page(self, page_name, data, parent_id=None): rsp = self.rest_client.post('content', new_page) if 'id' not in rsp: - api_err = ('Confluence reports a successful page ' + - 'creation; however, provided no ' + - 'identifier.\n\n') + api_err = ( + 'Confluence reports a successful page ' + 'creation; however, provided no identifier.\n\n' + ) try: api_err += 'DATA: {}'.format(json.dumps( rsp, indent=2)) @@ -908,8 +917,10 @@ def store_page(self, page_name, data, parent_id=None): self.store_page_properties(uploaded_page_id, props) except ConfluencePermissionError as ex: - msg = 'Publish user does not have permission to add page ' \ - 'content to the configured space.' + msg = ( + 'Publish user does not have permission to add page ' + 'content to the configured space.' + ) raise ConfluencePermissionError(msg) from ex if not self.watch: @@ -959,8 +970,10 @@ def store_page_by_id(self, page_name, page_id, data): try: self._update_page(page, page_name, data) except ConfluencePermissionError as ex: - msg = 'Publish user does not have permission to add page ' \ - 'content to the configured space.' + msg = ( + 'Publish user does not have permission to add page ' + 'content to the configured space.' + ) raise ConfluencePermissionError(msg) from ex if not self.watch: @@ -1003,8 +1016,10 @@ def remove_attachment(self, id_): try: self.rest_client.delete('content', id_) except ConfluencePermissionError as ex: - msg = 'Publish user does not have permission to delete ' \ - 'from the configured space.' + msg = ( + 'Publish user does not have permission to delete ' + 'from the configured space.' + ) raise ConfluencePermissionError(msg) from ex def remove_page(self, page_id): @@ -1039,8 +1054,10 @@ def remove_page(self, page_id): logger.verbose('ignore missing delete for page ' f'identifier: {page_id}') except ConfluencePermissionError as ex: - msg = 'Publish user does not have permission to delete ' \ - 'from the configured space.' + msg = ( + 'Publish user does not have permission to delete ' + 'from the configured space.' + ) raise ConfluencePermissionError(msg) from ex def restrict_ancestors(self, ancestors): @@ -1078,8 +1095,10 @@ def update_space_home(self, page_id): 'type': self.space_type, }) except ConfluencePermissionError as ex: - msg = 'Publish user does not have permission to update ' \ - "space's homepage." + msg = ( + 'Publish user does not have permission to update ' + "space's homepage." + ) raise ConfluencePermissionError(msg) from ex def _build_page(self, page_name, data): diff --git a/sphinxcontrib/confluencebuilder/state.py b/sphinxcontrib/confluencebuilder/state.py index ae67d327..ff5a3bbb 100644 --- a/sphinxcontrib/confluencebuilder/state.py +++ b/sphinxcontrib/confluencebuilder/state.py @@ -226,8 +226,10 @@ def _format_postfix(postfix, docname, config): hash=ConfluenceState._create_docname_unique_hash(docname, config), ) except KeyError as ex: - msg = f"Configured confluence_publish_prefix '{postfix}' has " \ - "an unknown template replacement." + msg = ( + f"Configured confluence_publish_prefix '{postfix}' has " + 'an unknown template replacement.' + ) raise ConfluenceConfigError(msg) from ex return postfix From 899eaab8a06a66d18008bcf40f045276b0acacbb Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 16:42:08 -0500 Subject: [PATCH 07/26] use suppressible exception over try-except-pass Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/config/defaults.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/config/defaults.py b/sphinxcontrib/confluencebuilder/config/defaults.py index cc04c526..a3ac7d44 100644 --- a/sphinxcontrib/confluencebuilder/config/defaults.py +++ b/sphinxcontrib/confluencebuilder/config/defaults.py @@ -4,6 +4,7 @@ from pathlib import Path from sphinxcontrib.confluencebuilder.debug import PublishDebug from sphinxcontrib.confluencebuilder.util import str2bool +import contextlib # configures the default editor to publication @@ -131,7 +132,5 @@ def apply_defaults(builder): # if the parent page is an integer value in a string type, cast it to an # integer; otherwise, assume it is a page name (string) if conf.confluence_parent_page: - try: + with contextlib.suppress(ValueError): conf.confluence_parent_page = int(conf.confluence_parent_page) - except ValueError: - pass From dd149216ba03c53c4fb3119aa97b1c5ca44ed05b Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 16:49:51 -0500 Subject: [PATCH 08/26] remove various variable/function shadowing Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/builder.py | 6 +++--- sphinxcontrib/confluencebuilder/directives.py | 4 ++-- sphinxcontrib/confluencebuilder/env.py | 6 +++--- sphinxcontrib/confluencebuilder/intersphinx.py | 7 +++---- tests/unit-tests/test_legacy_pages.py | 12 ++++++------ 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/builder.py b/sphinxcontrib/confluencebuilder/builder.py index f14f0bb6..b930f2c4 100644 --- a/sphinxcontrib/confluencebuilder/builder.py +++ b/sphinxcontrib/confluencebuilder/builder.py @@ -1129,9 +1129,9 @@ def _register_doctree_title_targets(self, docname, doctree): if section_id > 0: target = f'{target}.{section_id}' - for id_ in section_node['ids']: - id_ = f'{docname}#{id_}' - self.state.register_target(id_, target) + for raw_id in section_node['ids']: + full_id = f'{docname}#{raw_id}' + self.state.register_target(full_id, target) def _top_ref_check(self, node): """ diff --git a/sphinxcontrib/confluencebuilder/directives.py b/sphinxcontrib/confluencebuilder/directives.py index 5d7df2e0..ab493ea5 100644 --- a/sphinxcontrib/confluencebuilder/directives.py +++ b/sphinxcontrib/confluencebuilder/directives.py @@ -35,8 +35,8 @@ def string_list(argument): if argument: for line in argument.splitlines(): - for label in line.strip().split(' '): - label = label.strip() + for label_entry in line.strip().split(' '): + label = label_entry.strip() if label: data.append(label) diff --git a/sphinxcontrib/confluencebuilder/env.py b/sphinxcontrib/confluencebuilder/env.py index 86596607..e51c557c 100644 --- a/sphinxcontrib/confluencebuilder/env.py +++ b/sphinxcontrib/confluencebuilder/env.py @@ -145,7 +145,7 @@ def track_page_hash(self, docname): return doc_hash - def track_last_page_id(self, docname, id): + def track_last_page_id(self, docname, page_id): """ track the last publish page identifier for a document @@ -155,10 +155,10 @@ def track_last_page_id(self, docname, id): Args: docname: the name of the document - id: the page identifier + page_id: the page identifier """ - self._active_pids[docname] = id + self._active_pids[docname] = page_id self._cached_pids.pop(docname, None) def load_cache(self): diff --git a/sphinxcontrib/confluencebuilder/intersphinx.py b/sphinxcontrib/confluencebuilder/intersphinx.py index e5300b29..4c4eaa4b 100644 --- a/sphinxcontrib/confluencebuilder/intersphinx.py +++ b/sphinxcontrib/confluencebuilder/intersphinx.py @@ -70,12 +70,11 @@ def escape(string): else: anchor = '' - uri = pages_part.format(page_id) + uri = pages_part_fmt.format(page_id) if anchor: uri += '#' + anchor - if dispname == name: - dispname = '-' - entry = f'{name} {domainname}:{typ} {prio} {uri} {dispname}\n' + display = '-' if dispname == name else dispname + entry = f'{name} {domainname}:{typ} {prio} {uri} {display}\n' logger.verbose('(intersphinx) ' + entry.strip()) f.write(compressor.compress(entry.encode('utf-8'))) diff --git a/tests/unit-tests/test_legacy_pages.py b/tests/unit-tests/test_legacy_pages.py index 080b6985..1f4b4e0f 100644 --- a/tests/unit-tests/test_legacy_pages.py +++ b/tests/unit-tests/test_legacy_pages.py @@ -132,17 +132,17 @@ def remove_page(self, page_id): self.removed.append(page_name) def store_page(self, page_name, data, parent_id=None): - id = self.page2id.get(page_name) - if not id: - id = self.base_page_idx + page_id = self.page2id.get(page_name) + if not page_id: + page_id = self.base_page_idx self.base_page_idx += 1 - self.page2id[page_name] = id - self.id2page[id] = page_name + self.page2id[page_name] = page_id + self.id2page[page_id] = page_name self.published.append(page_name) - return id + return page_id # other unused methods From c3e1074f84373ca7a88ebdb94de27d8c21ff7f28 Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 16:59:36 -0500 Subject: [PATCH 09/26] remove superfluous else return Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/compat.py | 4 +- sphinxcontrib/confluencebuilder/publisher.py | 54 ++++++++++--------- .../confluencebuilder/singlebuilder.py | 4 +- sphinxcontrib/confluencebuilder/util.py | 19 +++---- 4 files changed, 42 insertions(+), 39 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/compat.py b/sphinxcontrib/confluencebuilder/compat.py index 13b9a2d8..ac2294cc 100644 --- a/sphinxcontrib/confluencebuilder/compat.py +++ b/sphinxcontrib/confluencebuilder/compat.py @@ -16,8 +16,8 @@ def docutils_findall(doctree, *args, **kwargs): if docutils_version_info >= (0, 18, 1): return doctree.findall(*args, **kwargs) - else: - return doctree.traverse(*args, **kwargs) + + return doctree.traverse(*args, **kwargs) # use sphinx's inline_all_toctrees which supports the `replace` argument; diff --git a/sphinxcontrib/confluencebuilder/publisher.py b/sphinxcontrib/confluencebuilder/publisher.py index 05ba0bf1..3c7ed71f 100644 --- a/sphinxcontrib/confluencebuilder/publisher.py +++ b/sphinxcontrib/confluencebuilder/publisher.py @@ -106,7 +106,8 @@ def archive_page(self, page_id): if self.dryrun: self._dryrun('archive page', page_id) return - elif self.onlynew: + + if self.onlynew: self._onlynew('page archive restricted', page_id) return @@ -143,7 +144,8 @@ def archive_pages(self, page_ids): if self.dryrun: self._dryrun('archiving pages', ', '.join(page_ids)) return - elif self.onlynew: + + if self.onlynew: self._onlynew('page archiving restricted', ', '.join(page_ids)) return @@ -619,10 +621,11 @@ def store_attachment(self, page_id, name, data, mimetype, hash_, force=False): if not attachment: self._dryrun('adding new attachment ' + name) return None - else: - self._dryrun('updating existing attachment', attachment['id']) - return attachment['id'] - elif self.onlynew and attachment: + + self._dryrun('updating existing attachment', attachment['id']) + return attachment['id'] + + if self.onlynew and attachment: self._onlynew('skipping existing attachment', attachment['id']) return attachment['id'] @@ -733,18 +736,18 @@ def store_page(self, page_name, data, parent_id=None): if not page: self._dryrun('adding new page ' + page_name) return None - else: - misc = '' - if parent_id and 'ancestors' in page: - if not any(a['id'] == parent_id for a in page['ancestors']): - if parent_id in self._name_cache: - misc += '[new parent page {} ({})]'.format( - self._name_cache[parent_id], parent_id) - else: - misc += '[new parent page]' - - self._dryrun('updating existing page', page['id'], misc) - return page['id'] + + misc = '' + if parent_id and 'ancestors' in page: + if not any(a['id'] == parent_id for a in page['ancestors']): + if parent_id in self._name_cache: + misc += '[new parent page {} ({})]'.format( + self._name_cache[parent_id], parent_id) + else: + misc += '[new parent page]' + + self._dryrun('updating existing page', page['id'], misc) + return page['id'] # fetch the page data # (expand on certain fields that may be required) @@ -952,9 +955,9 @@ def store_page_by_id(self, page_name, page_id, data): if not page: self._dryrun('unable to find page with id', page_id) return None - else: - self._dryrun('updating existing page', page_id) - return page_id + + self._dryrun('updating existing page', page_id) + return page_id expand = 'version' if self.append_labels: @@ -1009,7 +1012,8 @@ def remove_attachment(self, id_): if self.dryrun: self._dryrun('removing attachment', id_) return - elif self.onlynew: + + if self.onlynew: self._onlynew('attachment removal restricted', id_) return @@ -1026,7 +1030,8 @@ def remove_page(self, page_id): if self.dryrun: self._dryrun('removing page', page_id) return - elif self.onlynew: + + if self.onlynew: self._onlynew('page removal restricted', page_id) return @@ -1082,7 +1087,8 @@ def update_space_home(self, page_id): if self.dryrun: self._dryrun('updating space home to', page_id) return - elif self.onlynew: + + if self.onlynew: self._onlynew('space home updates restricted') return diff --git a/sphinxcontrib/confluencebuilder/singlebuilder.py b/sphinxcontrib/confluencebuilder/singlebuilder.py index fa051537..3c0986bc 100644 --- a/sphinxcontrib/confluencebuilder/singlebuilder.py +++ b/sphinxcontrib/confluencebuilder/singlebuilder.py @@ -60,8 +60,8 @@ def get_relative_uri(self, from_, to, typ=None): def get_target_uri(self, docname, typ=None): if docname in self.env.all_docs: return f'{self.config.root_doc}{self.link_suffix}#{docname}' - else: - return self.link_transform(docname) + + return self.link_transform(docname) def write(self, build_docnames, updated_docnames, method='update'): docnames = self.env.all_docs diff --git a/sphinxcontrib/confluencebuilder/util.py b/sphinxcontrib/confluencebuilder/util.py index d646d253..eba5e333 100644 --- a/sphinxcontrib/confluencebuilder/util.py +++ b/sphinxcontrib/confluencebuilder/util.py @@ -309,8 +309,8 @@ def getpass2(prompt='Password: '): subprocess.check_call(['stty', 'echo']) print('') return value - else: - return getpass.getpass(prompt=prompt) + + return getpass.getpass(prompt=prompt) def handle_cli_file_subset(builder, option, value): @@ -338,15 +338,12 @@ def handle_cli_file_subset(builder, option, value): # (and not an empty list); if no values are detected, # return `None` return None - else: - target_file = Path(value) - if not target_file.is_absolute(): - target_file = Path(builder.env.srcdir, value) - - if target_file.is_file(): - value = target_file - else: - value = value.split(',') + + target_file = Path(value) + if not target_file.is_absolute(): + target_file = Path(builder.env.srcdir, value) + + value = target_file if target_file.is_file() else value.split(',') return value From 5b1502fb7492421319cf779f939d4a30e6b6b5e5 Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 17:02:08 -0500 Subject: [PATCH 10/26] add exception chaining on various exceptions Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/config/validation.py | 12 ++++++------ sphinxcontrib/confluencebuilder/directives.py | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/config/validation.py b/sphinxcontrib/confluencebuilder/config/validation.py index d5cbad71..d3b20190 100644 --- a/sphinxcontrib/confluencebuilder/config/validation.py +++ b/sphinxcontrib/confluencebuilder/config/validation.py @@ -219,9 +219,9 @@ def enum(self, etype): if value is not None and not isinstance(value, etype): try: value = etype[value.lower()] - except (AttributeError, KeyError): + except (AttributeError, KeyError) as ex: msg = f'{self.key} is not an enumeration ({etype.__name__})' - raise ConfluenceConfigError(msg) + raise ConfluenceConfigError(msg) from ex return self @@ -275,9 +275,9 @@ def float_(self, positive=False): if isinstance(value, str): try: value = float(value) - except ValueError: + except ValueError as ex: msg = f'{self.key} is not a float string' - raise ConfluenceConfigError(msg) + raise ConfluenceConfigError(msg) from ex elif isinstance(value, int): value = float(value) @@ -316,9 +316,9 @@ def int_(self, positive=False): if isinstance(value, str): try: value = int(value) - except ValueError: + except ValueError as ex: msg = f'{self.key} is not an integer string' - raise ConfluenceConfigError(msg) + raise ConfluenceConfigError(msg) from ex if positive: if not isinstance(value, int) or value <= 0: diff --git a/sphinxcontrib/confluencebuilder/directives.py b/sphinxcontrib/confluencebuilder/directives.py index ab493ea5..dc887fc6 100644 --- a/sphinxcontrib/confluencebuilder/directives.py +++ b/sphinxcontrib/confluencebuilder/directives.py @@ -306,9 +306,9 @@ def run(self): if 'serverId' in params: try: UUID(params['serverId'], version=4) - except ValueError: + except ValueError as ex: msg = 'server-id is not a valid uuid' - raise self.error(msg) + raise self.error(msg) from ex return [node] From fa3c8498dfdb9c6bb5cea0e92fa32f0692ebb710 Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 17:06:42 -0500 Subject: [PATCH 11/26] add trailing commas (COM812) Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/std/confluence.py | 4 ++-- tests/sample-sets/sphinx-data-viewer/conf.py | 4 ++-- tests/sample-sets/sphinx-needs/conf.py | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/std/confluence.py b/sphinxcontrib/confluencebuilder/std/confluence.py index 8bf4c044..af2b0f40 100644 --- a/sphinxcontrib/confluencebuilder/std/confluence.py +++ b/sphinxcontrib/confluencebuilder/std/confluence.py @@ -157,7 +157,7 @@ # highlight type as the target language for the default type. # # [1]: http://www.sphinx-doc.org/en/stable/config.html#confval-highlight_language - DEFAULT_HIGHLIGHT_STYLE: 'python' + DEFAULT_HIGHLIGHT_STYLE: 'python', } LITERAL2LANG_MAP_V2 = { @@ -402,7 +402,7 @@ # highlight type as the target language for the default type. # # [1]: http://www.sphinx-doc.org/en/stable/config.html#confval-highlight_language - DEFAULT_HIGHLIGHT_STYLE: 'python' + DEFAULT_HIGHLIGHT_STYLE: 'python', } # sphinx literal to confluence language map (fallbacks) diff --git a/tests/sample-sets/sphinx-data-viewer/conf.py b/tests/sample-sets/sphinx-data-viewer/conf.py index a54c0e02..c612a6a4 100644 --- a/tests/sample-sets/sphinx-data-viewer/conf.py +++ b/tests/sample-sets/sphinx-data-viewer/conf.py @@ -8,6 +8,6 @@ "my_data": { "name": "Mario", "job": "plumber", - "magic_tubes": [2, 7, 23, 43.5] - } + "magic_tubes": [2, 7, 23, 43.5], + }, } diff --git a/tests/sample-sets/sphinx-needs/conf.py b/tests/sample-sets/sphinx-needs/conf.py index d07f3014..debd36e2 100644 --- a/tests/sample-sets/sphinx-needs/conf.py +++ b/tests/sample-sets/sphinx-needs/conf.py @@ -19,9 +19,9 @@ 'head': ['**<>** for *<>*'], 'meta': ['**status**: <>', '**author**: <>'], - 'side': ['<>'] - } - } + 'side': ['<>'], + }, + }, } # html builder options (to compare) From 23951dbf52f0e4f43a42256f5884aedf16d372f1 Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 17:08:00 -0500 Subject: [PATCH 12/26] remove unnecessary parenthesis Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/config/validation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinxcontrib/confluencebuilder/config/validation.py b/sphinxcontrib/confluencebuilder/config/validation.py index d3b20190..e0e86c94 100644 --- a/sphinxcontrib/confluencebuilder/config/validation.py +++ b/sphinxcontrib/confluencebuilder/config/validation.py @@ -284,7 +284,7 @@ def float_(self, positive=False): if positive: if not isinstance(value, float) or value <= 0: msg = f'{self.key} is not a positive float' - raise ConfluenceConfigError() + raise ConfluenceConfigError elif not isinstance(value, float) or value < 0: msg = f'{self.key} is not a non-negative float' raise ConfluenceConfigError(msg) From 96c98c5d576fdf357dfb01a494dab71b702987d6 Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 17:11:01 -0500 Subject: [PATCH 13/26] simplify verbose lines Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/publisher.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/publisher.py b/sphinxcontrib/confluencebuilder/publisher.py index 3c7ed71f..0e7cc1d3 100644 --- a/sphinxcontrib/confluencebuilder/publisher.py +++ b/sphinxcontrib/confluencebuilder/publisher.py @@ -889,8 +889,7 @@ def store_page(self, page_name, data, parent_id=None): if str(ex).find('title already exists') == -1: raise - logger.verbose('title already exists warning ' - f'for page {page_name}') + logger.verbose(f'title already exists for page {page_name}') _, page = self.get_page_case_insensitive(page_name) if not page: @@ -1056,8 +1055,7 @@ def remove_page(self, page_id): if str(ex).find('No content found with id') == -1: raise - logger.verbose('ignore missing delete for page ' - f'identifier: {page_id}') + logger.verbose(f'ignore missing delete for page id: {page_id}') except ConfluencePermissionError as ex: msg = ( 'Publish user does not have permission to delete ' From 82623a1d9edd4f5f1a81414cac5ff46498213a5b Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 17:16:01 -0500 Subject: [PATCH 14/26] explicit stty paths for getpass override Update stty calls to use an explicit path, to prevent any unexpected PATH overrides. Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/util.py b/sphinxcontrib/confluencebuilder/util.py index eba5e333..a92dd1b6 100644 --- a/sphinxcontrib/confluencebuilder/util.py +++ b/sphinxcontrib/confluencebuilder/util.py @@ -302,11 +302,11 @@ def getpass2(prompt='Password: '): # disable this feature. if (os.name == 'nt' and 'MSYSTEM' in os.environ and 'TERM' in os.environ and 'CONFLUENCEBUILDER_NO_GETPASS_HOOK' not in os.environ): - subprocess.check_call(['stty', '-echo']) + subprocess.check_call(['/usr/bin/stty', '-echo']) try: value = input(prompt) finally: - subprocess.check_call(['stty', 'echo']) + subprocess.check_call(['/usr/bin/stty', 'echo']) print('') return value From 13f9a8467ce7fc8256b49347d6d6c56b0146423b Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 17:22:31 -0500 Subject: [PATCH 15/26] suppress linter warning on aliased locale translation function Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/storage/index.py | 2 +- sphinxcontrib/confluencebuilder/storage/search.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/storage/index.py b/sphinxcontrib/confluencebuilder/storage/index.py index 01872fba..678fb5ad 100644 --- a/sphinxcontrib/confluencebuilder/storage/index.py +++ b/sphinxcontrib/confluencebuilder/storage/index.py @@ -3,7 +3,7 @@ from pathlib import Path from sphinx.environment.adapters.indexentries import IndexEntries -from sphinxcontrib.confluencebuilder.locale import L as sccb_translation +from sphinxcontrib.confluencebuilder.locale import L as sccb_translation # noqa: N811 from sphinxcontrib.confluencebuilder.state import ConfluenceState from sphinxcontrib.confluencebuilder.storage import intern_uri_anchor_value import pkgutil diff --git a/sphinxcontrib/confluencebuilder/storage/search.py b/sphinxcontrib/confluencebuilder/storage/search.py index cfdf2287..7d295f26 100644 --- a/sphinxcontrib/confluencebuilder/storage/search.py +++ b/sphinxcontrib/confluencebuilder/storage/search.py @@ -2,7 +2,7 @@ # Copyright Sphinx Confluence Builder Contributors (AUTHORS) from pathlib import Path -from sphinxcontrib.confluencebuilder.locale import L as sccb_translation +from sphinxcontrib.confluencebuilder.locale import L as sccb_translation # noqa: N811 import pkgutil From c334d8a3569f0ba170bf5bb091e30c1b607e2bcd Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 17:27:34 -0500 Subject: [PATCH 16/26] suppress linter subprocess warnings on non-input calls Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/util.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/util.py b/sphinxcontrib/confluencebuilder/util.py index a92dd1b6..30f51ac3 100644 --- a/sphinxcontrib/confluencebuilder/util.py +++ b/sphinxcontrib/confluencebuilder/util.py @@ -302,11 +302,11 @@ def getpass2(prompt='Password: '): # disable this feature. if (os.name == 'nt' and 'MSYSTEM' in os.environ and 'TERM' in os.environ and 'CONFLUENCEBUILDER_NO_GETPASS_HOOK' not in os.environ): - subprocess.check_call(['/usr/bin/stty', '-echo']) + subprocess.check_call(['/usr/bin/stty', '-echo']) # noqa: S603 try: value = input(prompt) finally: - subprocess.check_call(['/usr/bin/stty', 'echo']) + subprocess.check_call(['/usr/bin/stty', 'echo']) # noqa: S603 print('') return value From 0de7c90cb61c86140e9ba988a5c1addd8f3410f7 Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 17:29:24 -0500 Subject: [PATCH 17/26] suppress linter security warning on random call The existing implementation to randomizing the delay for request tries is not a security concern. Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/rest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sphinxcontrib/confluencebuilder/rest.py b/sphinxcontrib/confluencebuilder/rest.py index adcad05c..15975691 100644 --- a/sphinxcontrib/confluencebuilder/rest.py +++ b/sphinxcontrib/confluencebuilder/rest.py @@ -124,7 +124,7 @@ def _wrapper(self, *args, **kwargs): delay = min(delay, RATE_LIMITED_MAX_RETRY_DURATION) # add jitter - delay += random.uniform(0.3, 1.3) + delay += random.uniform(0.3, 1.3) # noqa: S311 # wait the calculated delay before retrying again logger.warn('rate-limit response detected; ' From de012bdcf129307dad5a43f9965829acb3f17ee5 Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 17:33:12 -0500 Subject: [PATCH 18/26] tests: explicit capture of builder init call There is no difference between capturing the init call explicitly or via the `getattr` style; updating to the simpler variant. Signed-off-by: James Knight --- tests/unit-tests/test_legacy_pages.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit-tests/test_legacy_pages.py b/tests/unit-tests/test_legacy_pages.py index 1f4b4e0f..1db14961 100644 --- a/tests/unit-tests/test_legacy_pages.py +++ b/tests/unit-tests/test_legacy_pages.py @@ -24,7 +24,7 @@ def test_legacy_pages(self): # prepare a mocked publisher that we can emulate publishing events # and check if legacy pages are properly remain/purged - old_init = getattr(ConfluenceBuilder, 'init') + old_init = ConfluenceBuilder.init publisher = MockedPublisher() def wrapped_init(builder): From 4ec94db1de745d070f6a625680a45f522be4e73c Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 17:35:06 -0500 Subject: [PATCH 19/26] simplify various attribute set-exists checks Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/builder.py | 2 +- sphinxcontrib/confluencebuilder/storage/translator.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/builder.py b/sphinxcontrib/confluencebuilder/builder.py index b930f2c4..df47e64c 100644 --- a/sphinxcontrib/confluencebuilder/builder.py +++ b/sphinxcontrib/confluencebuilder/builder.py @@ -440,7 +440,7 @@ def write_doc(self, docname, doctree): if ids: for node in findall(doctree, nodes.reference): - if 'refid' in node and node['refid']: + if node.get('refid'): top_ref = node['refid'] in ids # allow a derived class to hint if this is a #top diff --git a/sphinxcontrib/confluencebuilder/storage/translator.py b/sphinxcontrib/confluencebuilder/storage/translator.py index b281c5f4..8abcba0d 100644 --- a/sphinxcontrib/confluencebuilder/storage/translator.py +++ b/sphinxcontrib/confluencebuilder/storage/translator.py @@ -1256,8 +1256,7 @@ def visit_reference(self, node): node['refid'] = node['refuri'][1:] del node['refuri'] self._visit_reference_intern_id(node) - elif 'refdocname' in node or ( - 'internal' in node and node['internal']): + elif 'refdocname' in node or node.get('internal'): self._visit_reference_intern_uri(node) else: self._visit_reference_extern(node) From 0ff05038b56637d8d04a5e7df576e2641fcba0eb Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 17:40:16 -0500 Subject: [PATCH 20/26] remove superfluous else return Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/cmd/wipe.py | 11 +++++++---- sphinxcontrib/confluencebuilder/util.py | 8 +++++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/cmd/wipe.py b/sphinxcontrib/confluencebuilder/cmd/wipe.py index 9c580475..b53ae57a 100644 --- a/sphinxcontrib/confluencebuilder/cmd/wipe.py +++ b/sphinxcontrib/confluencebuilder/cmd/wipe.py @@ -195,11 +195,14 @@ def ask_question(question, default='no'): while True: rsp = input(question + prompt).strip().lower() + if default is not None and rsp == '': return default == 'yes' - elif rsp in ('y', 'yes'): + + if rsp in ('y', 'yes'): return True - elif rsp in ('n', 'no', 'q'): # q for 'quit' + + if rsp in ('n', 'no', 'q'): # q for 'quit' return False - else: - print("Please respond with 'y' or 'n'.\n") + + print("Please respond with 'y' or 'n'.\n") diff --git a/sphinxcontrib/confluencebuilder/util.py b/sphinxcontrib/confluencebuilder/util.py index 30f51ac3..66f71673 100644 --- a/sphinxcontrib/confluencebuilder/util.py +++ b/sphinxcontrib/confluencebuilder/util.py @@ -386,12 +386,14 @@ def str2bool(value): """ value = str(value).lower() + if value in ['y', 'yes', 't', 'true', 'on', '1']: return True - elif value in ['n', 'no', 'f', 'false', 'off', '0']: + + if value in ['n', 'no', 'f', 'false', 'off', '0']: return False - else: - raise ValueError + + raise ValueError @contextmanager From f7ccc2281baba70e84fd27b5da4ba9d7b42dfc44 Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 17:52:42 -0500 Subject: [PATCH 21/26] suppress xml recursion warnings for trusted svg/sites The use of XML parsers targets user-provided SVGs and only targets users Confluence instances (in debug cases). It is expected that these are trusted sources for users, so adding noqa's for any linter warnings. Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/cmd/report.py | 2 +- sphinxcontrib/confluencebuilder/svg.py | 2 +- tests/unit-tests/test_svg.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/cmd/report.py b/sphinxcontrib/confluencebuilder/cmd/report.py index 952c52ec..31ec8966 100644 --- a/sphinxcontrib/confluencebuilder/cmd/report.py +++ b/sphinxcontrib/confluencebuilder/cmd/report.py @@ -172,7 +172,7 @@ def report_main(args_parser): # parse print('parsing information...') - xml_data = ElementTree.fromstring(raw_data) + xml_data = ElementTree.fromstring(raw_data) # noqa: S314 info += ' parsed: yes\n' root = ElementTree.ElementTree(xml_data) for o in root.findall('typeId'): diff --git a/sphinxcontrib/confluencebuilder/svg.py b/sphinxcontrib/confluencebuilder/svg.py index fe80bbbb..3d30f19b 100644 --- a/sphinxcontrib/confluencebuilder/svg.py +++ b/sphinxcontrib/confluencebuilder/svg.py @@ -77,7 +77,7 @@ def confluence_supported_svg(builder, node): return modified = False - svg_root = xml_et.fromstring(svg_data) + svg_root = xml_et.fromstring(svg_data) # noqa: S314 # determine (if possible) the svgs desired width/height svg_height = None diff --git a/tests/unit-tests/test_svg.py b/tests/unit-tests/test_svg.py index 6e3f9211..c447a230 100644 --- a/tests/unit-tests/test_svg.py +++ b/tests/unit-tests/test_svg.py @@ -18,7 +18,7 @@ def _extract_svg_size(self, svg_file): with svg_file.open('rb') as f: svg_data = f.read() - svg_root = xml_et.fromstring(svg_data) + svg_root = xml_et.fromstring(svg_data) # noqa: S314 return int(svg_root.attrib['width']), int(svg_root.attrib['height']) @setup_builder('confluence') From 1d29624dbda91063c7691eee182d80a9b510c138 Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 18:06:32 -0500 Subject: [PATCH 22/26] config: provide defaults for legacy search-mode handling When searching for legacy configuration options using `getattr`, ensure defaults are provided to avoid undesired `AttributeError` exceptions. This logic was intended to not throw exceptions, but never properly added the default cases to avoid it. Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/config/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/config/__init__.py b/sphinxcontrib/confluencebuilder/config/__init__.py index 993e4e07..73c60cc1 100644 --- a/sphinxcontrib/confluencebuilder/config/__init__.py +++ b/sphinxcontrib/confluencebuilder/config/__init__.py @@ -29,8 +29,8 @@ def legacy(new, orig): legacy('confluence_root_homepage', 'confluence_master_homepage') legacy('confluence_space_key', 'confluence_space_name') - if getattr(config, 'confluence_adv_aggressive_search') is True: - if getattr(config, 'confluence_cleanup_search_mode') is None: + if getattr(config, 'confluence_adv_aggressive_search', None) is True: + if getattr(config, 'confluence_cleanup_search_mode', None) is None: config['confluence_cleanup_search_mode'] = 'search-aggressive' From e922c1b1b744c6ff8fca3faec9effdc4090000d2 Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 22:50:47 -0500 Subject: [PATCH 23/26] config: move publish-debug opts into except block Publish debug options are only relevant to the exception raised in the configuration's exception block; moving. Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/config/checks.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/config/checks.py b/sphinxcontrib/confluencebuilder/config/checks.py index 92d73b72..45dae47b 100644 --- a/sphinxcontrib/confluencebuilder/config/checks.py +++ b/sphinxcontrib/confluencebuilder/config/checks.py @@ -491,8 +491,6 @@ def conf_translate(value): # ################################################################## - opts = PublishDebug._member_names_ # pylint: disable=no-member - # confluence_publish_debug try: validator.conf('confluence_publish_debug').bool() # deprecated @@ -500,6 +498,7 @@ def conf_translate(value): try: validator.conf('confluence_publish_debug').enum(PublishDebug) except ConfluenceConfigError as ex: + opts = PublishDebug._member_names_ # pylint: disable=no-member opts_str = '\n - '.join(opts) raise ConfluencePublishDebugConfigError(ex, opts_str) from ex From e3bf7b9187ed755f7d152054d282d62b9816bf7b Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 22:56:15 -0500 Subject: [PATCH 24/26] remove obsolete linter hints Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/builder.py | 2 +- sphinxcontrib/confluencebuilder/rest.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/builder.py b/sphinxcontrib/confluencebuilder/builder.py index df47e64c..8d42511f 100644 --- a/sphinxcontrib/confluencebuilder/builder.py +++ b/sphinxcontrib/confluencebuilder/builder.py @@ -47,7 +47,7 @@ class ConfluenceBuilder(Builder): allow_parallel = True default_translator_class = ConfluenceStorageFormatTranslator name = 'confluence' - format = 'confluence_storage' # noqa: A003 + format = 'confluence_storage' supported_image_types = ConfluenceSupportedImages() supported_linkcode = True supported_remote_images = True diff --git a/sphinxcontrib/confluencebuilder/rest.py b/sphinxcontrib/confluencebuilder/rest.py index 15975691..2e0ea10a 100644 --- a/sphinxcontrib/confluencebuilder/rest.py +++ b/sphinxcontrib/confluencebuilder/rest.py @@ -219,7 +219,7 @@ def _setup_session(self, config): elif config.confluence_server_user: passwd = config.confluence_server_pass if passwd is None: - passwd = '' # noqa: S105 + passwd = '' session.auth = (config.confluence_server_user, passwd) if config.confluence_server_cookies: From 85e01cac2b7359c81a7a9c687f3a58ad95123b34 Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 23:00:15 -0500 Subject: [PATCH 25/26] various linter tweaks Tweaking a series of loops, ifs and exception to cleaning up linter warnings when running ruff. Signed-off-by: James Knight --- sphinxcontrib/confluencebuilder/cmd/wipe.py | 5 ++--- sphinxcontrib/confluencebuilder/directives.py | 5 ++--- sphinxcontrib/confluencebuilder/intersphinx.py | 6 ++---- sphinxcontrib/confluencebuilder/publisher.py | 9 +++------ sphinxcontrib/confluencebuilder/rest.py | 3 ++- 5 files changed, 11 insertions(+), 17 deletions(-) diff --git a/sphinxcontrib/confluencebuilder/cmd/wipe.py b/sphinxcontrib/confluencebuilder/cmd/wipe.py index b53ae57a..c30dbac3 100644 --- a/sphinxcontrib/confluencebuilder/cmd/wipe.py +++ b/sphinxcontrib/confluencebuilder/cmd/wipe.py @@ -147,9 +147,8 @@ def wipe_main(args_parser): if args.verbose: print('-------------------------') - page_names = [] - for p in legacy_pages: - page_names.append(publisher._name_cache[p]) + name_cache = publisher._name_cache # noqa: SLF001 + page_names = [name_cache[p] for p in legacy_pages] sorted(page_names) print('\n'.join(page_names)) print('-------------------------') diff --git a/sphinxcontrib/confluencebuilder/directives.py b/sphinxcontrib/confluencebuilder/directives.py index dc887fc6..ff31869e 100644 --- a/sphinxcontrib/confluencebuilder/directives.py +++ b/sphinxcontrib/confluencebuilder/directives.py @@ -361,6 +361,5 @@ def kebab_case_to_camel_case(s): Returns: the converted string """ - s = ''.join(list(map(lambda x: x.capitalize(), s.split('-')))) - s = s[0].lower() + s[1:] - return s + s = ''.join(x.capitalize() for x in s.split('-')) + return s[0].lower() + s[1:] diff --git a/sphinxcontrib/confluencebuilder/intersphinx.py b/sphinxcontrib/confluencebuilder/intersphinx.py index 4c4eaa4b..7e8a536b 100644 --- a/sphinxcontrib/confluencebuilder/intersphinx.py +++ b/sphinxcontrib/confluencebuilder/intersphinx.py @@ -26,10 +26,8 @@ def build_intersphinx(builder): def escape(string): return re.sub("\\s+", ' ', string) - if builder.cloud: - pages_part = 'pages/{}/' - else: - pages_part = 'pages/viewpage.action?pageId={}' + pages_part_fmt = 'pages/' + pages_part_fmt += '{}/' if builder.cloud else 'viewpage.action?pageId={}' inventory_db = builder.out_dir / INVENTORY_FILENAME with inventory_db.open('wb') as f: diff --git a/sphinxcontrib/confluencebuilder/publisher.py b/sphinxcontrib/confluencebuilder/publisher.py index 0e7cc1d3..d6634dab 100644 --- a/sphinxcontrib/confluencebuilder/publisher.py +++ b/sphinxcontrib/confluencebuilder/publisher.py @@ -778,10 +778,7 @@ def store_page(self, page_name, data, parent_id=None): return page['id'] # fetch known properties (associated with this extension) from the page - if page: - props = self.get_page_properties(page['id']) - else: - props = None + props = self.get_page_properties(page['id']) if page else None # calculate the hash for a page; we will first use this to check if # there is a update to apply, and if we do need to update, we will @@ -912,8 +909,8 @@ def store_page(self, page_name, data, parent_id=None): }, } else: - last_props_version = int(props['version']['number']) - props['version']['number'] = last_props_version + 1 + last_props_version = int(props['version']['number']) # pylint: disable=unsubscriptable-object + props['version']['number'] = last_props_version + 1 # pylint: disable=unsubscriptable-object props['value']['hash'] = new_page_hash self.store_page_properties(uploaded_page_id, props) diff --git a/sphinxcontrib/confluencebuilder/rest.py b/sphinxcontrib/confluencebuilder/rest.py index 2e0ea10a..e6ad9ebf 100644 --- a/sphinxcontrib/confluencebuilder/rest.py +++ b/sphinxcontrib/confluencebuilder/rest.py @@ -387,7 +387,8 @@ def _process_request(self, method, path, *args, **kwargs): if rsp.status_code == 401: raise ConfluenceAuthenticationFailedUrlError if rsp.status_code == 403: - raise ConfluencePermissionError('rest-call') + msg = 'rest-call' + raise ConfluencePermissionError(msg) if rsp.status_code == 407: raise ConfluenceProxyPermissionError if rsp.status_code == 429: From 4666d8cbfa1c9d589c422f25501e47bb97989a13 Mon Sep 17 00:00:00 2001 From: James Knight Date: Sat, 2 Mar 2024 23:02:13 -0500 Subject: [PATCH 26/26] tox: bump ruff version Signed-off-by: James Knight --- ruff.toml | 4 ++-- tox.ini | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ruff.toml b/ruff.toml index 30590c6b..3c038996 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,8 +1,8 @@ -select = [ +lint.select = [ 'ALL', ] -ignore = [ +lint.ignore = [ # various translator/role/etc. definitions may not use all/any arguments 'ARG001', 'ARG002', diff --git a/tox.ini b/tox.ini index 9c4db3b9..b22d139d 100644 --- a/tox.ini +++ b/tox.ini @@ -67,9 +67,10 @@ commands = [testenv:ruff] deps = {[testenv]deps} - ruff + ruff: ruff==0.3.0 commands = ruff \ + check \ sphinxcontrib \ tests