From 87aaff5764143fdc9672f924f65ed9aa64afbbf5 Mon Sep 17 00:00:00 2001 From: Matthew Duane Hardcastle Date: Tue, 2 Jul 2024 10:59:09 -0400 Subject: [PATCH 1/3] [Py3] Remove cpickle if not supported Py3 drops the cPickle library. This ensure's it's not used if it doesn't exist. re: https://github.com/chrisbro/alfred-bear/issues/33 --- workflow/workflow.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/workflow/workflow.py b/workflow/workflow.py index 4fd8db4..3c746b8 100644 --- a/workflow/workflow.py +++ b/workflow/workflow.py @@ -24,7 +24,6 @@ import atexit import binascii from contextlib import contextmanager -import cPickle from copy import deepcopy import errno import json @@ -47,6 +46,13 @@ except ImportError: # pragma: no cover import xml.etree.ElementTree as ET +SUPPORTS_CPICKLE = True +try: + import cPickle +except ImportError: + cPickle = None + SUPPORTS_CPICKLE = False + #: Sentinel for properties that haven't been set yet (that might #: correctly have the value ``None``) @@ -698,7 +704,8 @@ def dump(cls, obj, file_obj): # Set up default manager and register built-in serializers manager = SerializerManager() -manager.register('cpickle', CPickleSerializer) +if SUPPORTS_CPICKLE: + manager.register('cpickle', CPickleSerializer) manager.register('pickle', PickleSerializer) manager.register('json', JSONSerializer) @@ -1120,8 +1127,11 @@ def __init__(self, default_settings=None, update_settings=None, self._bundleid = None self._debugging = None self._name = None - self._cache_serializer = 'cpickle' - self._data_serializer = 'cpickle' + self._cache_serializer = 'pickle' + self._data_serializer = 'pickle' + if SUPPORTS_CPICKLE: + self._cache_serializer = 'cpickle' + self._data_serializer = 'cpickle' self._info = None self._info_loaded = False self._logger = None From b8b91f7930620abeab34459ca8abfe0dd947a8b6 Mon Sep 17 00:00:00 2001 From: Matthew Duane Hardcastle Date: Tue, 2 Jul 2024 15:37:26 -0400 Subject: [PATCH 2/3] [Py3] support relative and package imports The update called in the context of the plugin and its own shell. These context have different package paths. The plugin must import through relative paths, while the shell must import through package paths. This change ensures both context work. There's probably a more elegant way of resolving this issue. ;) The change also reverse the circular import fix to make resolving the relative import in Py3 easier since the fix can exist in oneplace rather than multiple imports statements. re: https://github.com/chrisbro/alfred-bear/issues/33 --- workflow/background.py | 3 +-- workflow/update.py | 12 +++++++++--- workflow/workflow.py | 19 +++++++++---------- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/workflow/background.py b/workflow/background.py index 7bda3f5..90358e6 100644 --- a/workflow/background.py +++ b/workflow/background.py @@ -17,8 +17,6 @@ import subprocess import pickle -from workflow import Workflow - __all__ = ['is_running', 'run_in_background'] _wf = None @@ -27,6 +25,7 @@ def wf(): global _wf if _wf is None: + from workflow import Workflow _wf = Workflow() return _wf diff --git a/workflow/update.py b/workflow/update.py index bb8e9da..8c85940 100644 --- a/workflow/update.py +++ b/workflow/update.py @@ -29,7 +29,13 @@ import subprocess import workflow -import web + +try: + from .web import get as web_get +except (ImportError, ValueError): + # ValueError is thrown is py2 + # ImportError is thrown is py3 + from web import get as web_get # __all__ = [] @@ -212,7 +218,7 @@ def download_workflow(url): wf().logger.debug( 'Downloading updated workflow from `%s` to `%s` ...', url, local_path) - response = web.get(url) + response = web_get(url) with open(local_path, 'wb') as output: output.write(response.content) @@ -311,7 +317,7 @@ def get_valid_releases(github_slug, prereleases=False): def retrieve_releases(): wf().logger.info( 'Retrieving releases for `%s` ...', github_slug) - return web.get(api_url).json() + return web_get(api_url).json() slug = github_slug.replace('/', '-') for release in wf().cached_data('gh-releases-{0}'.format(slug), diff --git a/workflow/workflow.py b/workflow/workflow.py index 3c746b8..53578ac 100644 --- a/workflow/workflow.py +++ b/workflow/workflow.py @@ -46,6 +46,15 @@ except ImportError: # pragma: no cover import xml.etree.ElementTree as ET +try: + from .background import run_in_background + from .update import Version +except (ValueError, ImportError): + # ValueError is thrown is py2 + # ImportError is thrown is py3 + from background import _process_exists, run_in_background + from update import Version + SUPPORTS_CPICKLE = True try: import cPickle @@ -53,7 +62,6 @@ cPickle = None SUPPORTS_CPICKLE = False - #: Sentinel for properties that haven't been set yet (that might #: correctly have the value ``None``) UNSET = object() @@ -870,7 +878,6 @@ def _validate_lockfile(self): except ValueError: return self.release() - from background import _process_exists if not _process_exists(pid): self.release() @@ -1172,7 +1179,6 @@ def __init__(self, default_settings=None, update_settings=None, @property def alfred_version(self): """Alfred version as :class:`~workflow.update.Version` object.""" - from update import Version return Version(self.alfred_env.get('version')) @property @@ -1353,7 +1359,6 @@ def version(self): version = self.info.get('version') if version: - from update import Version version = Version(version) self._version = version @@ -2395,7 +2400,6 @@ def last_version_run(self): version = self.settings.get('__workflow_last_version') if version: - from update import Version version = Version(version) self._last_version_run = version @@ -2425,7 +2429,6 @@ def set_last_version(self, version=None): version = self.version if isinstance(version, basestring): - from update import Version version = Version(version) self.settings['__workflow_last_version'] = str(version) @@ -2504,8 +2507,6 @@ def check_update(self, force=False): # version = self._update_settings['version'] version = str(self.version) - from background import run_in_background - # update.py is adjacent to this file update_script = os.path.join(os.path.dirname(__file__), b'update.py') @@ -2544,8 +2545,6 @@ def start_update(self): if not update.check_update(github_slug, version, self.prereleases): return False - from background import run_in_background - # update.py is adjacent to this file update_script = os.path.join(os.path.dirname(__file__), b'update.py') From b295a82254b440322af43b2bbcc6a48d18335b22 Mon Sep 17 00:00:00 2001 From: Matthew Duane Hardcastle Date: Fri, 5 Jul 2024 11:05:00 -0400 Subject: [PATCH 3/3] More relative imports --- workflow/workflow.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/workflow/workflow.py b/workflow/workflow.py index 53578ac..c267918 100644 --- a/workflow/workflow.py +++ b/workflow/workflow.py @@ -48,12 +48,12 @@ try: from .background import run_in_background - from .update import Version + from .update import check_update, Version except (ValueError, ImportError): # ValueError is thrown is py2 # ImportError is thrown is py3 from background import _process_exists, run_in_background - from update import Version + from update import check_update, Version SUPPORTS_CPICKLE = True try: @@ -2536,13 +2536,11 @@ def start_update(self): installed, else ``False`` """ - import update - github_slug = self._update_settings['github_slug'] # version = self._update_settings['version'] version = str(self.version) - if not update.check_update(github_slug, version, self.prereleases): + if not check_update(github_slug, version, self.prereleases): return False # update.py is adjacent to this file