def env(self): if ispy3: env = os.environ.copy() else: # We use this inefficient method of copying the environment variables # because of non ascii env vars on windows. See https://bugs.launchpad.net/bugs/811191 env = {} for key in os.environ: try: val = os.environ[key] if isinstance(val, unicode_type): # On windows subprocess cannot handle unicode env vars try: val = val.encode(filesystem_encoding) except ValueError: val = val.encode('utf-8') if isinstance(key, unicode_type): key = key.encode('ascii') env[key] = val except: pass env[native_string_type('CALIBRE_WORKER')] = environ_item('1') td = as_hex_unicode(msgpack_dumps(base_dir())) env[native_string_type('CALIBRE_WORKER_TEMP_DIR')] = environ_item(td) env.update(self._env) return env
def env(self): env = os.environ.copy() env[native_string_type('CALIBRE_WORKER')] = environ_item('1') td = as_hex_unicode(msgpack_dumps(base_dir())) env[native_string_type('CALIBRE_WORKER_TEMP_DIR')] = environ_item(td) env.update(self._env) return env
def env(self): if ispy3: env = os.environ.copy() else: # We use this inefficient method of copying the environment variables # because of non ascii env vars on windows. See https://bugs.launchpad.net/bugs/811191 env = {} for key in os.environ: try: val = os.environ[key] if isinstance(val, unicode_type): # On windows subprocess cannot handle unicode env vars try: val = val.encode(filesystem_encoding) except ValueError: val = val.encode('utf-8') if isinstance(key, unicode_type): key = key.encode('ascii') env[key] = val except: pass env[native_string_type('CALIBRE_WORKER')] = environ_item('1') td = as_hex_unicode(msgpack_dumps(base_dir())) env[native_string_type('CALIBRE_WORKER_TEMP_DIR')] = environ_item(td) env.update(self._env) return env
def options_iter(self): for opt in self.option_list: if native_string_type(opt).strip(): yield opt for gr in self.option_groups: for opt in gr.option_list: if native_string_type(opt).strip(): yield opt
def get_smtp_class(use_ssl=False, debuglevel=0): # We need this as in python 3.7 we have to pass the hostname # in the constructor, because of https://bugs.python.org/issue36094 # which means the constructor calls connect(), # but there is no way to set debuglevel before connect() is called import polyglot.smtplib as smtplib cls = smtplib.SMTP_SSL if use_ssl else smtplib.SMTP bases = (cls,) return type(native_string_type('SMTP'), bases, {native_string_type('debuglevel'): debuglevel})
def parser(name, field_map, default_field_name=None): field_map = dict((x.split(':') for x in field_map.split())) def parse(raw, log=None): ans = {} last_option = None raw = raw.replace('\\\\', '\x01').replace('\\"', '\x02') for token, token_type in scanner.scan(raw)[0]: token = token.replace('\x01', '\\').replace('\x02', '"') if token_type is FLAG: last_option = field_map.get(token[1], null) if last_option is not None: ans[last_option] = None elif token_type is WORD: if last_option is None: ans[default_field_name] = token else: ans[last_option] = token last_option = None ans.pop(null, None) return ans parse.__name__ = native_string_type('parse_' + name) return parse
def __init__(self, stream): self.stream = stream or sys.stdout self.isatty = getattr(self.stream, 'isatty', lambda : False)() force_ansi = 'CALIBRE_FORCE_ANSI' in os.environ if not self.isatty and force_ansi: self.isatty = True self.isansi = force_ansi or not iswindows self.set_console = self.write_console = None self.is_console = False if not self.isansi: try: import msvcrt self.msvcrt = msvcrt self.file_handle = msvcrt.get_osfhandle(self.stream.fileno()) from ctypes import windll, wintypes, byref, POINTER, WinDLL mode = wintypes.DWORD(0) f = windll.kernel32.GetConsoleMode f.argtypes, f.restype = [wintypes.HANDLE, POINTER(wintypes.DWORD)], wintypes.BOOL if f(self.file_handle, byref(mode)): # Stream is a console self.set_console = windll.kernel32.SetConsoleTextAttribute self.default_console_text_attributes = WCOLORS['white'] kernel32 = WinDLL(native_string_type('kernel32'), use_last_error=True) self.write_console = kernel32.WriteConsoleW self.write_console.argtypes = [wintypes.HANDLE, wintypes.c_wchar_p, wintypes.DWORD, POINTER(wintypes.DWORD), wintypes.LPVOID] self.write_console.restype = wintypes.BOOL kernel32.GetConsoleScreenBufferInfo.argtypes = [wintypes.HANDLE, ctypes.POINTER(CONSOLE_SCREEN_BUFFER_INFO)] kernel32.GetConsoleScreenBufferInfo.restype = wintypes.BOOL csbi = CONSOLE_SCREEN_BUFFER_INFO() if kernel32.GetConsoleScreenBufferInfo(self.file_handle, byref(csbi)): self.default_console_text_attributes = csbi.wAttributes self.is_console = True except: pass
def __enter__(self): while not self.loop.ready and self.is_alive(): time.sleep(0.01) self.address = self.loop.bound_address[:2] os.environ['CALIBRE_AUTORELOAD_PORT'] = native_string_type( self.address[1]) return self
def first_index(raw, queries): for q in queries: try: return raw.index(native_string_type(q)) except ValueError: pass return -1
def __call__(self, redirect_output=True, cwd=None, priority=None): ''' If redirect_output is True, output from the child is redirected to a file on disk and this method returns the path to that file. ''' exe = self.gui_executable if self.gui else self.executable env = self.env try: origwd = cwd or os.path.abspath(getcwd()) except EnvironmentError: # cwd no longer exists origwd = cwd or os.path.expanduser('~') env[native_string_type('ORIGWD')] = environ_item( as_hex_unicode(msgpack_dumps(origwd))) _cwd = cwd if priority is None: priority = prefs['worker_process_priority'] cmd = [exe] if isinstance(exe, string_or_bytes) else exe args = { 'env': env, 'cwd': _cwd, } if iswindows: priority = { 'high': subprocess.HIGH_PRIORITY_CLASS, 'normal': subprocess.NORMAL_PRIORITY_CLASS, 'low': subprocess.IDLE_PRIORITY_CLASS }[priority] args['creationflags'] = subprocess.CREATE_NO_WINDOW | priority else: niceness = { 'normal': 0, 'low': 10, 'high': 20, }[priority] args['env']['CALIBRE_WORKER_NICENESS'] = str(niceness) ret = None if redirect_output: self._file = PersistentTemporaryFile('_worker_redirect.log') args['stdout'] = self._file._fd args['stderr'] = subprocess.STDOUT if iswindows: args['stdin'] = subprocess.PIPE ret = self._file.name if iswindows and 'stdin' not in args: # On windows when using the pythonw interpreter, # stdout, stderr and stdin may not be valid args['stdin'] = subprocess.PIPE args['stdout'] = windows_null_file args['stderr'] = subprocess.STDOUT self.child = subprocess.Popen(cmd, **args) if 'stdin' in args: self.child.stdin.close() self.log_path = ret return ret
def isoformat(date_time, assume_utc=False, as_utc=True, sep='T'): if not hasattr(date_time, 'tzinfo'): return unicode_type(date_time.isoformat()) if date_time.tzinfo is None: date_time = date_time.replace( tzinfo=_utc_tz if assume_utc else _local_tz) date_time = date_time.astimezone(_utc_tz if as_utc else _local_tz) # native_string_type(sep) because isoformat barfs with unicode sep on python 2.x return unicode_type(date_time.isoformat(native_string_type(sep)))
def test_dlls(self): import win32api base = win32api.GetDllDirectory() for x in os.listdir(base): if x.lower().endswith('.dll'): try: ctypes.WinDLL(native_string_type(os.path.join(base, x))) except Exception as err: self.assertTrue(False, 'Failed to load DLL %s with error: %s' % (x, err))
def _build_meta(self): _, meta = self._oeb.to_opf1()[OPF_MIME] meta.attrib['ms--minimum_level'] = '0' meta.attrib['ms--attr5'] = '1' meta.attrib['ms--guid'] = '{%s}' % native_string_type(uuid.uuid4()).upper() rebin = ReBinary(meta, None, self._oeb, self.opts, map=OPF_MAP) meta = rebin.content self._meta = meta self._add_file('/meta', meta)
def as_unicode(obj, enc=preferred_encoding): if not isbytestring(obj): try: obj = unicode_type(obj) except Exception: try: obj = native_string_type(obj) except Exception: obj = repr(obj) return force_unicode(obj, enc=enc)
def as_unicode(obj, enc=preferred_encoding): if not isbytestring(obj): try: obj = unicode_type(obj) except Exception: try: obj = native_string_type(obj) except Exception: obj = repr(obj) return force_unicode(obj, enc=enc)
def run_worker(mod, func, **kw): try: exe = [ sys.executable, os.path.join(sys.setup_dir, 'run-calibre-worker.py') ] except AttributeError: exe = [ os.path.join(os.path.dirname(os.path.abspath(sys.executable)), 'calibre-parallel' + ('.exe' if iswindows else '')) ] env = kw.get('env', os.environ.copy()) env['CALIBRE_SIMPLE_WORKER'] = mod + ':' + func if iswindows: kw['creationflags'] = subprocess.CREATE_NO_WINDOW kw['env'] = { native_string_type(k): native_string_type(v) for k, v in iteritems(env) } # windows needs bytes in env return subprocess.Popen(exe, **kw)
def convert_metadata(self, mi): namespaces = self.namespace.namespaces E = ElementMaker(namespace=namespaces['cp'], nsmap={x:namespaces[x] for x in 'cp dc dcterms xsi'.split()}) cp = E.coreProperties(E.revision("1"), E.lastModifiedBy('calibre')) ts = utcnow().isoformat(native_string_type('T')).rpartition('.')[0] + 'Z' for x in 'created modified'.split(): x = cp.makeelement('{%s}%s' % (namespaces['dcterms'], x), **{'{%s}type' % namespaces['xsi']:'dcterms:W3CDTF'}) x.text = ts cp.append(x) self.mi = mi update_doc_props(cp, self.mi, self.namespace) return xml2str(cp)
def do_connect(path, row_factory=None): conn = sqlite.connect(path, factory=Connection) conn.execute('pragma cache_size=-5000') encoding = conn.execute('pragma encoding').fetchone()[0] conn.create_aggregate('sortconcat', 2, SortedConcatenate) conn.create_aggregate('sortconcat_bar', 2, SortedConcatenateBar) conn.create_aggregate('sortconcat_amper', 2, SortedConcatenateAmper) conn.create_aggregate('identifiers_concat', 2, IdentifiersConcat) load_c_extensions(conn) conn.row_factory = sqlite.Row if row_factory else ( lambda cursor, row: list(row)) conn.create_aggregate('concat', 1, Concatenate) conn.create_aggregate('aum_sortconcat', 4, AumSortedConcatenate) conn.create_collation(native_string_type('PYNOCASE'), partial(pynocase, encoding=encoding)) conn.create_function('title_sort', 1, title_sort) conn.create_function('author_to_author_sort', 1, _author_to_author_sort) conn.create_function('uuid4', 0, lambda: unicode_type(uuid.uuid4())) # Dummy functions for dynamically created filters conn.create_function('books_list_filter', 1, lambda x: 1) conn.create_collation(native_string_type('icucollate'), icu_collator) return conn
def __init__(self, stream): self.stream = stream or sys.stdout self.isatty = getattr(self.stream, 'isatty', lambda: False)() force_ansi = 'CALIBRE_FORCE_ANSI' in os.environ if not self.isatty and force_ansi: self.isatty = True self.isansi = force_ansi or not iswindows self.set_console = self.write_console = None self.is_console = False if not self.isansi: try: import msvcrt self.msvcrt = msvcrt self.file_handle = msvcrt.get_osfhandle(self.stream.fileno()) from ctypes import windll, wintypes, byref, POINTER, WinDLL mode = wintypes.DWORD(0) f = windll.kernel32.GetConsoleMode f.argtypes, f.restype = [ wintypes.HANDLE, POINTER(wintypes.DWORD) ], wintypes.BOOL if f(self.file_handle, byref(mode)): # Stream is a console self.set_console = windll.kernel32.SetConsoleTextAttribute self.default_console_text_attributes = WCOLORS['white'] kernel32 = WinDLL(native_string_type('kernel32'), use_last_error=True) self.write_console = kernel32.WriteConsoleW self.write_console.argtypes = [ wintypes.HANDLE, wintypes.c_wchar_p, wintypes.DWORD, POINTER(wintypes.DWORD), wintypes.LPVOID ] self.write_console.restype = wintypes.BOOL kernel32.GetConsoleScreenBufferInfo.argtypes = [ wintypes.HANDLE, ctypes.POINTER(CONSOLE_SCREEN_BUFFER_INFO) ] kernel32.GetConsoleScreenBufferInfo.restype = wintypes.BOOL csbi = CONSOLE_SCREEN_BUFFER_INFO() if kernel32.GetConsoleScreenBufferInfo( self.file_handle, byref(csbi)): self.default_console_text_attributes = csbi.wAttributes self.is_console = True except: pass
def load_plugin(self, name): if name in self._plugins: return sys.path.insert(0, plugins_loc) try: del sys.modules[name] except KeyError: pass plugin_err = '' try: p = importlib.import_module(name) except Exception as err: p = None try: plugin_err = unicode_type(err) except Exception: plugin_err = as_unicode(native_string_type(err), encoding=preferred_encoding, errors='replace') self._plugins[name] = p, plugin_err sys.path.remove(plugins_loc)
def prints(*args, **kwargs): ''' Print unicode arguments safely by encoding them to preferred_encoding Has the same signature as the print function from Python 3, except for the additional keyword argument safe_encode, which if set to True will cause the function to use repr when encoding fails. Returns the number of bytes written. ''' file = kwargs.get('file', sys.stdout) file = getattr(file, 'buffer', file) enc = 'utf-8' if hasenv('CALIBRE_WORKER') else preferred_encoding sep = kwargs.get('sep', ' ') if not isinstance(sep, bytes): sep = sep.encode(enc) end = kwargs.get('end', '\n') if not isinstance(end, bytes): end = end.encode(enc) safe_encode = kwargs.get('safe_encode', False) count = 0 for i, arg in enumerate(args): if isinstance(arg, unicode_type): if iswindows: from calibre.utils.terminal import Detect cs = Detect(file) if cs.is_console: cs.write_unicode_text(arg) count += len(arg) if i != len(args)-1: file.write(sep) count += len(sep) continue try: arg = arg.encode(enc) except UnicodeEncodeError: try: arg = arg.encode('utf-8') except: if not safe_encode: raise arg = repr(arg) if not isinstance(arg, bytes): try: arg = native_string_type(arg) except ValueError: arg = unicode_type(arg) if isinstance(arg, unicode_type): try: arg = arg.encode(enc) except UnicodeEncodeError: try: arg = arg.encode('utf-8') except: if not safe_encode: raise arg = repr(arg) try: file.write(arg) count += len(arg) except: from polyglot import reprlib arg = reprlib.repr(arg) file.write(arg) count += len(arg) if i != len(args)-1: file.write(sep) count += len(sep) file.write(end) count += len(end) return count
def __str__(self): return native_string_type(self._values)
def add_option_group(self, *args, **kwargs): if isinstance(args[0], string_or_bytes): args = list(args) args[0] = native_string_type(args[0]) return optparse.OptionParser.add_option_group(self, *args, **kwargs)
def __call__(self, redirect_output=True, cwd=None, priority=None): ''' If redirect_output is True, output from the child is redirected to a file on disk and this method returns the path to that file. ''' exe = self.gui_executable if self.gui else self.executable env = self.env try: origwd = cwd or os.path.abspath(os.getcwdu()) except EnvironmentError: # cwd no longer exists origwd = cwd or os.path.expanduser(u'~') env[native_string_type('ORIGWD')] = environ_item(as_hex_unicode(msgpack_dumps(origwd))) _cwd = cwd if priority is None: priority = prefs['worker_process_priority'] cmd = [exe] if isinstance(exe, string_or_bytes) else exe args = { 'env' : env, 'cwd' : _cwd, } if iswindows: priority = { 'high' : win32process.HIGH_PRIORITY_CLASS, 'normal' : win32process.NORMAL_PRIORITY_CLASS, 'low' : win32process.IDLE_PRIORITY_CLASS}[priority] args['creationflags'] = win32process.CREATE_NO_WINDOW|priority else: niceness = { 'normal' : 0, 'low' : 10, 'high' : 20, }[priority] args['preexec_fn'] = partial(renice, niceness) ret = None if redirect_output: self._file = PersistentTemporaryFile('_worker_redirect.log') args['stdout'] = self._file._fd args['stderr'] = subprocess.STDOUT if iswindows: args['stdin'] = subprocess.PIPE ret = self._file.name if iswindows and 'stdin' not in args: # On windows when using the pythonw interpreter, # stdout, stderr and stdin may not be valid args['stdin'] = subprocess.PIPE args['stdout'] = windows_null_file args['stderr'] = subprocess.STDOUT if not iswindows: # Close inherited file descriptors in worker # On windows, this is done in the worker process # itself args['close_fds'] = True self.child = subprocess.Popen(cmd, **args) if 'stdin' in args: self.child.stdin.close() self.log_path = ret return ret
if descriptor._emits_changed_signal is not None: value = { True: "true", False: "false", "invalidates": "invalidates" }[descriptor._emits_changed_signal] reflection_data += '>\n <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="%s"/>\n </property>\n' % ( value, ) else: reflection_data += ' />\n' return reflection_data # Define Interface as an instance of the metaclass InterfaceType, in a way # that is compatible across both Python 2 and Python 3. Interface = InterfaceType(native_string_type('Interface'), (object, ), {}) class PropertiesInterface(Interface): """An object with properties must inherit from this interface.""" def _get_decorator(self, interface_name, property_name): interfaces = self._dbus_interface_table if interface_name: interface = interfaces.get(interface_name) if interface is None: raise DBusException("No interface %s on object" % interface_name) prop = interface.get(property_name) if prop is None: raise DBusException("No property %s on object interface %s" % (property_name, interface_name))
def add_option_group(self, *args, **kwargs): if isinstance(args[0], string_or_bytes): args = list(args) args[0] = native_string_type(args[0]) return optparse.OptionParser.add_option_group(self, *args, **kwargs)
def __str__(self): return native_string_type(self._values)
def print_xml(elem): from calibre.ebooks.lrf.pylrs.pylrs import ElementWriter elem = elem.toElement(native_string_type('utf8')) ew = ElementWriter(elem, sourceEncoding=native_string_type('utf8')) ew.write(sys.stdout) print()
from polyglot.builtins import native_string_type class ConversionUserFeedBack(Exception): def __init__(self, title, msg, level='info', det_msg=''): ''' Show a simple message to the user :param title: The title (very short description) :param msg: The message to show the user :param level: Must be one of 'info', 'warn' or 'error' :param det_msg: Optional detailed message to show the user ''' import json Exception.__init__( self, json.dumps({ 'msg': msg, 'level': level, 'det_msg': det_msg, 'title': title })) self.title, self.msg, self.det_msg = title, msg, det_msg self.level = level # Ensure exception uses fully qualified name as this is used to detect it in # the GUI. ConversionUserFeedBack.__name__ = native_string_type( 'calibre.ebooks.conversion.ConversionUserFeedBack')
class JavascriptLexer(RegexLexer): """ For JavaScript source code. This is based on the pygments JS highlighter, bu that does not handle multi-line comments in streaming mode, so we had to modify it. """ flags = re.UNICODE | re.MULTILINE tokens = { native_string_type('commentsandwhitespace'): [(r'\s+', Text), (r'<!--', Comment), (r'//.*?$', Comment.Single), (r'/\*', Comment.Multiline, native_string_type('comment'))], native_string_type('comment'): [ (r'[^*/]+', Comment.Multiline), (r'\*/', Comment.Multiline, native_string_type('#pop')), (r'[*/]', Comment.Multiline), ], native_string_type('slashstartsregex'): [ include(native_string_type('commentsandwhitespace')), (r'/(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/' r'([gim]+\b|\B)', String.Regex, native_string_type('#pop')), (r'(?=/)', Text, (native_string_type('#pop'), native_string_type('badregex'))), default(native_string_type('#pop')) ], native_string_type('badregex'): [(r'\n', Text, native_string_type('#pop'))], native_string_type('root'): [ (r'\A#! ?/.*?\n', Comment), # shebang lines are recognized by node.js (r'^(?=\s|/|<!--)', Text, native_string_type('slashstartsregex')), include(native_string_type('commentsandwhitespace')), (r'\+\+|--|~|&&|\?|:|\|\||\\(?=\n)|' r'(<<|>>>?|==?|!=?|[-<>+*%&|^/])=?', Operator, native_string_type('slashstartsregex')), (r'[{(\[;,]', Punctuation, native_string_type('slashstartsregex')), (r'[})\].]', Punctuation), (r'(for|in|while|do|break|return|continue|switch|case|default|if|else|' r'throw|try|catch|finally|new|delete|typeof|instanceof|void|yield|' r'this)\b', Keyword, native_string_type('slashstartsregex')), (r'(var|let|with|function)\b', Keyword.Declaration, native_string_type('slashstartsregex')), (r'(abstract|boolean|byte|char|class|const|debugger|double|enum|export|' r'extends|final|float|goto|implements|import|int|interface|long|native|' r'package|private|protected|public|short|static|super|synchronized|throws|' r'transient|volatile)\b', Keyword.Reserved), (r'(true|false|null|NaN|Infinity|undefined)\b', Keyword.Constant), (r'(Array|Boolean|Date|Error|Function|Math|netscape|' r'Number|Object|Packages|RegExp|String|sun|decodeURI|' r'decodeURIComponent|encodeURI|encodeURIComponent|' r'Error|eval|isFinite|isNaN|parseFloat|parseInt|document|this|' r'window)\b', Name.Builtin), (JS_IDENT, Name.Other), (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float), (r'0x[0-9a-fA-F]+', Number.Hex), (r'[0-9]+', Number.Integer), (r'"(\\\\|\\"|[^"])*"', String.Double), (r"'(\\\\|\\'|[^'])*'", String.Single), ] }
def __repr__(self): return native_string_type(self)
def prints(*args, **kwargs): ''' Print unicode arguments safely by encoding them to preferred_encoding Has the same signature as the print function from Python 3, except for the additional keyword argument safe_encode, which if set to True will cause the function to use repr when encoding fails. Returns the number of bytes written. ''' file = kwargs.get('file', sys.stdout) file = getattr(file, 'buffer', file) enc = 'utf-8' if hasenv('CALIBRE_WORKER') else preferred_encoding sep = kwargs.get('sep', ' ') if not isinstance(sep, bytes): sep = sep.encode(enc) end = kwargs.get('end', '\n') if not isinstance(end, bytes): end = end.encode(enc) safe_encode = kwargs.get('safe_encode', False) count = 0 for i, arg in enumerate(args): if isinstance(arg, unicode_type): if iswindows: from calibre.utils.terminal import Detect cs = Detect(file) if cs.is_console: cs.write_unicode_text(arg) count += len(arg) if i != len(args)-1: file.write(sep) count += len(sep) continue try: arg = arg.encode(enc) except UnicodeEncodeError: try: arg = arg.encode('utf-8') except: if not safe_encode: raise arg = repr(arg) if not isinstance(arg, bytes): try: arg = native_string_type(arg) except ValueError: arg = unicode_type(arg) if isinstance(arg, unicode_type): try: arg = arg.encode(enc) except UnicodeEncodeError: try: arg = arg.encode('utf-8') except: if not safe_encode: raise arg = repr(arg) try: file.write(arg) count += len(arg) except: from polyglot import reprlib arg = reprlib.repr(arg) file.write(arg) count += len(arg) if i != len(args)-1: file.write(sep) count += len(sep) file.write(end) count += len(end) return count
except: pass return parse_date(val, as_utc=False) return None convert_timestamp = _py_convert_timestamp if _c_speedup is None else \ _c_convert_timestamp def adapt_datetime(dt): return isoformat(dt, sep=' ') sqlite.register_adapter(datetime, adapt_datetime) sqlite.register_converter(native_string_type('timestamp'), convert_timestamp) def convert_bool(val): return val != '0' sqlite.register_adapter(bool, lambda x: 1 if x else 0) sqlite.register_converter(native_string_type('bool'), convert_bool) sqlite.register_converter(native_string_type('BOOL'), convert_bool) class DynamicFilter(object): def __init__(self, name): self.name = name self.ids = frozenset()
elif descriptor.fset: access = "write" else: return "" reflection_data = ' <property access="%s" type="%s" name="%s"' % (access, signature, descriptor.__name__) if descriptor._emits_changed_signal is not None: value = {True: "true", False: "false", "invalidates": "invalidates"}[descriptor._emits_changed_signal] reflection_data += '>\n <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="%s"/>\n </property>\n' % (value,) else: reflection_data += ' />\n' return reflection_data # Define Interface as an instance of the metaclass InterfaceType, in a way # that is compatible across both Python 2 and Python 3. Interface = InterfaceType(native_string_type('Interface'), (object,), {}) class PropertiesInterface(Interface): """An object with properties must inherit from this interface.""" def _get_decorator(self, interface_name, property_name): interfaces = self._dbus_interface_table if interface_name: interface = interfaces.get(interface_name) if interface is None: raise DBusException("No interface %s on object" % interface_name) prop = interface.get(property_name) if prop is None: raise DBusException("No property %s on object interface %s" % (property_name, interface_name)) if not isinstance(prop, dbus_property):