def test_deprecated_forwarded_setter(self, deprecated, current, forwarded, value): with warnings.catch_warnings(record=True) as w: called_method = getattr(self.settings, forwarded) # further mock out our mocked function so things work as they should called_method.__name__ = to_native_str(forwarded) called_method.__qualname__ = to_native_str(forwarded) called_method.__annotations__ = dict() method = getattr(self.plugin_settings, deprecated) self.assertTrue(callable(method)) method(["some_raw_key"], value) called_method.assert_called_once_with( ["plugins", self.plugin_key, "some_raw_key"], value, defaults=dict(plugins=dict(test_plugin=self.defaults)), preprocessors=dict(plugins=dict( test_plugin=self.set_preprocessors))) self.assertEqual(1, len(w)) self.assertTrue(issubclass(w[-1].category, DeprecationWarning)) self.assertTrue("{old} has been renamed to {new}".format( old=deprecated, new=current) in str(w[-1].message))
def __getattr__(self, item): all_access_methods = list(self.access_methods.keys()) + list( self.deprecated_access_methods.keys()) if item in all_access_methods: decorator = None if item in self.deprecated_access_methods: new = self.deprecated_access_methods[item] decorator = deprecated( "{old} has been renamed to {new}".format(old=item, new=new), stacklevel=2) item = new settings_name, args_mapper, kwargs_mapper = self.access_methods[ item] if hasattr(self.settings, settings_name) and callable( getattr(self.settings, settings_name)): orig_func = getattr(self.settings, settings_name) if decorator is not None: orig_func = decorator(orig_func) def _func(*args, **kwargs): return orig_func(*args_mapper(args), **kwargs_mapper(kwargs)) _func.__name__ = to_native_str(item) _func.__doc__ = orig_func.__doc__ if "__doc__" in dir( orig_func) else None return _func return getattr(self.settings, item)
def test_deprecated_global_setter(self, deprecated, current, forwarded, value): with warnings.catch_warnings(record=True) as w: called_method = getattr(self.settings, forwarded) called_method.__name__ = to_native_str(forwarded) method = getattr(self.plugin_settings, deprecated) self.assertTrue(callable(method)) method(["some_raw_key"], value) called_method.assert_called_once_with(["some_raw_key"], value) self.assertEqual(1, len(w)) self.assertTrue(issubclass(w[-1].category, DeprecationWarning)) self.assertTrue("{old} has been renamed to {new}".format(old=deprecated, new=current) in str(w[-1].message))
def test_mixins_matching_bases(self, bases_to_set, bases_to_check, expected): Foo = type(to_native_str("Foo"), bases_to_set, dict()) actual = octoprint.plugin.core.PluginManager.mixins_matching_bases(Foo, *bases_to_check) self.assertSetEqual(actual, set(expected))
def _check_pip_setup(self, pip_command): pip_command_str = pip_command if isinstance(pip_command_str, list): pip_command_str = " ".join(pip_command_str) with _cache_mutex: if not self.ignore_cache and pip_command_str in _cache["setup"]: self._logger.debug("Using cached pip setup information for {}".format(pip_command_str)) return _cache["setup"][pip_command_str] # This is horribly ugly and I'm sorry... # # While we can figure out the install directory, if that's writable and if a virtual environment # is active for pip that belongs to our sys.executable python instance by just checking some # variables, we can't for stuff like third party software we allow to update via the software # update plugin. # # What we do instead for these situations is try to install (and of course uninstall) the # testballoon dummy package, which collects that information for us. For pip <= 7 we could # have the testballoon provide us with the info needed through stdout, if pip was called # with --verbose anything printed to stdout within setup.py would be output. Pip 8 managed # to break this mechanism. Any (!) output within setup.py appears to be suppressed now, and # no combination of --log and multiple --verbose or -v arguments could get it to bring the # output back. # # So here's what we do now instead. Our sarge call sets an environment variable # "TESTBALLOON_OUTPUT" that points to a temporary file. If the testballoon sees that # variable set, it opens the file and writes to it the output it so far printed on stdout. # We then open the file and read in the data that way. # # Yeah, I'm not happy with that either. But as long as there's no way to otherwise figure # out for a generic pip command whether OctoPrint can even install anything with that # and if so how, well, that's how we'll have to do things. import os testballoon = os.path.join(os.path.realpath(os.path.dirname(__file__)), "piptestballoon") from octoprint.util import temppath with temppath() as testballoon_output_file: sarge_command = self.to_sarge_command(pip_command, "install", ".") try: # our testballoon is no real package, so this command will fail - that's ok though, # we only need the output produced within the pip environment sarge.run(sarge_command, stdout=sarge.Capture(), stderr=sarge.Capture(), cwd=testballoon, env=dict(TESTBALLOON_OUTPUT=to_native_str(testballoon_output_file))) except Exception: self._logger.exception("Error while trying to install testballoon to figure out pip setup") return False, False, False, None data = dict() with io.open(testballoon_output_file, 'rt', encoding='utf-8') as f: for line in f: key, value = line.split("=", 2) data[key] = value install_dir_str = data.get("PIP_INSTALL_DIR", None) virtual_env_str = data.get("PIP_VIRTUAL_ENV", None) writable_str = data.get("PIP_WRITABLE", None) if install_dir_str is not None and virtual_env_str is not None and writable_str is not None: install_dir = install_dir_str.strip() virtual_env = virtual_env_str.strip() == "True" writable = writable_str.strip() == "True" can_use_user_flag = not virtual_env and site.ENABLE_USER_SITE ok = writable or can_use_user_flag user_flag = not writable and can_use_user_flag self._logger.info("pip installs to {} (writable -> {}), --user flag needed -> {}, " "virtual env -> {}".format(install_dir, "yes" if writable else "no", "yes" if user_flag else "no", "yes" if virtual_env else "no")) self._logger.info("==> pip ok -> {}".format("yes" if ok else "NO!")) # ok, enable user flag, virtual env yes/no, installation dir result = ok, user_flag, virtual_env, install_dir _cache["setup"][pip_command_str] = result return result else: self._logger.error("Could not detect desired output from testballoon install, got this instead: {!r}".format(data)) return False, False, False, None
def _get_pluginblacklist_wizard_details(self): return dict(required=self._is_pluginblacklist_wizard_required()) def _get_pluginblacklist_wizard_name(self): return gettext("Plugin blacklist") def _get_pluginblacklist_additional_wizard_template_data(self): return dict(mandatory=self._is_pluginblacklist_wizard_required()) # noinspection PyUnresolvedReferences,PyMethodMayBeStatic class PrinterProfileSubwizard(object): def _is_printerprofile_wizard_firstrunonly(self): return True def _is_printerprofile_wizard_required(self): return self._printer_profile_manager.is_default_unmodified() and self._printer_profile_manager.profile_count == 1 def _get_printerprofile_wizard_details(self): return dict(required=self._is_printerprofile_wizard_required()) def _get_printerprofile_wizard_name(self): return gettext("Default Printer Profile") Subwizards = type(to_native_str("Subwizards"), tuple(cls for clsname, cls in inspect.getmembers(sys.modules[__name__], inspect.isclass) if clsname.endswith("Subwizard")), dict())
return dict(required=self._is_pluginblacklist_wizard_required()) def _get_pluginblacklist_wizard_name(self): return gettext("Plugin blacklist") def _get_pluginblacklist_additional_wizard_template_data(self): return dict(mandatory=self._is_pluginblacklist_wizard_required()) # noinspection PyUnresolvedReferences,PyMethodMayBeStatic class PrinterProfileSubwizard(object): def _is_printerprofile_wizard_firstrunonly(self): return True def _is_printerprofile_wizard_required(self): return self._printer_profile_manager.is_default_unmodified( ) and self._printer_profile_manager.profile_count == 1 def _get_printerprofile_wizard_details(self): return dict(required=self._is_printerprofile_wizard_required()) def _get_printerprofile_wizard_name(self): return gettext("Default Printer Profile") Subwizards = type( to_native_str("Subwizwards"), tuple(cls for clsname, cls in inspect.getmembers(sys.modules[__name__], inspect.isclass) if clsname.endswith("Subwizard")), dict())