···44444545 - uses: cachix/install-nix-action@526118121621777ccd86f79b04685a9319637641 # v31
46464747+ - uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
4848+ with:
4949+ # This cache is for the nixpkgs repo checks and should not be trusted or used elsewhere.
5050+ name: nixpkgs-ci
5151+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
5252+4753 - name: Build shell
4854 run: nix-build untrusted/ci -A shell
+6
.github/workflows/lib-tests.yml
···3232 with:
3333 extra_nix_config: sandbox = true
34343535+ - uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
3636+ with:
3737+ # This cache is for the nixpkgs repo checks and should not be trusted or used elsewhere.
3838+ name: nixpkgs-ci
3939+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
4040+3541 - name: Building Nixpkgs lib-tests
3642 run: |
3743 nix-build untrusted/ci -A lib-tests
···2828 - Applications linked against different Mesa versions than installed on the system should now work correctly going forward (however, applications against older Mesa, e.g. from Nixpkgs releases before 25.05, remain broken)
2929 - Packages that used to depend on Mesa for libgbm or libdri should use `libgbm` or `dri-pkgconfig-stub` as inputs, respectively
30303131+- GNU Taler has been updated to version 1.0.
3232+ This marks a significant milestone as the GNU Taler payment system is now available in Swiss Francs for individuals and businesses in Switzerland.
3333+ For more details, see the [upstream release notes](https://www.taler.net/en/news/2025-01.html).
3434+3135- OpenSSH has been updated from 9.9p2 to 10.0p2, dropping support for DSA keys and adding a new `ssh-auth` binary to handle user authentication in a different address space from unauthenticated sessions. See the [full changelog](https://www.openwall.com/lists/oss-security/2025/04/09/1) for more details.
32363337- Emacs has been updated to 30.1.
···2525 "secmod-eddsa"
2626 "secmod-rsa"
2727 ];
2828+2929+ configFile = config.environment.etc."taler/taler.conf".source;
2830in
29313032{
···4446 options = {
4547 # TODO: do we want this to be a sub-attribute or only define the exchange set of options here
4648 exchange = {
4747- AML_THRESHOLD = lib.mkOption {
4949+ CURRENCY = lib.mkOption {
5050+ type = lib.types.nonEmptyStr;
5151+ description = ''
5252+ The currency which the exchange will operate with. This cannot be changed later.
5353+ '';
5454+ };
5555+ CURRENCY_ROUND_UNIT = lib.mkOption {
4856 type = lib.types.str;
4949- default = "${cfgTaler.settings.taler.CURRENCY}:1000000";
5050- defaultText = "1000000 in {option}`CURRENCY`";
5151- description = "Monthly transaction volume until an account is considered suspicious and flagged for AML review.";
5757+ default = "${cfg.settings.exchange.CURRENCY}:0.01";
5858+ defaultText = "0.01 in {option}`CURRENCY`";
5959+ description = ''
6060+ Smallest amount in this currency that can be transferred using the underlying RTGS. For example: "EUR:0.01" or "JPY:1"
6161+ '';
5262 };
5363 DB = lib.mkOption {
5464 type = lib.types.enum [ "postgres" ];
···131141 after = [ "taler-exchange-httpd.service" ];
132142 };
133143134134- # Taken from https://docs.taler.net/taler-exchange-manual.html#exchange-database-setup
135135- # TODO: Why does aggregator need DELETE?
136136- systemd.services."taler-${talerComponent}-dbinit".script =
137137- let
138138- deletePerm = name: lib.optionalString (name == "aggregator") ",DELETE";
139139- dbScript = pkgs.writers.writeText "taler-exchange-db-permissions.sql" (
140140- lib.pipe servicesDB [
141141- (map (name: ''
142142- GRANT SELECT,INSERT,UPDATE${deletePerm name} ON ALL TABLES IN SCHEMA exchange TO "taler-exchange-${name}";
143143- GRANT USAGE ON SCHEMA exchange TO "taler-exchange-${name}";
144144- ''))
145145- lib.concatStrings
146146- ]
147147- );
148148- in
149149- ''
150150- ${lib.getExe' cfg.package "taler-exchange-dbinit"}
151151- psql -U taler-exchange-httpd -f ${dbScript}
152152- '';
144144+ systemd.services."taler-${talerComponent}-dbinit".script = ''
145145+ ${lib.getExe' cfg.package "taler-exchange-dbinit"} -c ${configFile}
146146+ '';
153147 };
154148}
+6-17
nixos/modules/services/finance/taler/merchant.nix
···1717 "webhook"
1818 "wirewatch"
1919 "depositcheck"
2020- "exchange"
2020+ "exchangekeyupdate"
2121 ];
2222+2323+ configFile = config.environment.etc."taler/taler.conf".source;
2224in
2325{
2426 imports = [
···8890 path = [ cfg.package ];
8991 };
90929191- systemd.services."taler-${talerComponent}-dbinit".script =
9292- let
9393- # NOTE: not documented, but is necessary
9494- dbScript = pkgs.writers.writeText "taler-merchant-db-permissions.sql" (
9595- lib.concatStrings (
9696- map (name: ''
9797- GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA merchant TO "taler-merchant-${name}";
9898- GRANT USAGE ON SCHEMA merchant TO "taler-merchant-${name}";
9999- '') servicesDB
100100- )
101101- );
102102- in
103103- ''
104104- ${lib.getExe' cfg.package "taler-merchant-dbinit"}
105105- psql -U taler-${talerComponent}-httpd -f ${dbScript}
106106- '';
9393+ systemd.services."taler-${talerComponent}-dbinit".script = ''
9494+ ${lib.getExe' cfg.package "taler-merchant-dbinit"} -c ${configFile}
9595+ '';
10796 };
10897}
···2121 postInstall = ''
2222 chmod -R u+w $out/share
2323 # Only include the files needed for runtime in the derivation
2424- mv $out/share/php/${finalAttrs.pname}/{migrations,public,src,config,bin,templates,tests,translations,vendor,symfony.lock,composer.json,composer.lock} $out
2424+ mv $out/share/php/davis/{migrations,public,src,config,bin,templates,tests,translations,vendor,symfony.lock,composer.json,composer.lock} $out
2525 # Save the upstream .env file for reference, but rename it so it is not loaded
2626- mv $out/share/php/${finalAttrs.pname}/.env $out/env-upstream
2626+ mv $out/share/php/davis/.env $out/env-upstream
2727 rm -rf "$out/share"
2828 '';
2929
···4949 # The package expect to find an `example-robot-data/robots` folder somewhere
5050 # either in install prefix or in the sources
5151 # where it can find the meshes for unit tests
5252- preCheck = "ln -s source ../../${finalAttrs.pname}";
5252+ preCheck = "ln -s source ../../example-robot-data";
5353 pythonImportsCheck = [ "example_robot_data" ];
54545555 meta = with lib; {
···11111212stdenvNoCC.mkDerivation (finalAttrs: {
1313 pname = "markdownlint-cli2";
1414- version = "0.17.2";
1414+ version = "0.18.1";
15151616 # upstream is not interested in including package-lock.json in the source
1717 # https://github.com/DavidAnson/markdownlint-cli2/issues/198#issuecomment-1690529976
···1919 # so use the tarball from the archlinux mirror
2020 src = fetchurl {
2121 url = "https://us.mirrors.cicku.me/archlinux/extra/os/x86_64/markdownlint-cli2-${finalAttrs.version}-1-any.pkg.tar.zst";
2222- hash = "sha256-TuiLFP/XItJh5VQWdwCvXRQCVzmqst4Sxna0eLobEQ4=";
2222+ hash = "sha256-M7qmhRDJGm2MhgS2oMfRrkLAst1Ye/rPCwP78UBbyyY=";
2323 };
24242525 nativeBuildInputs = [
···11+From 3161fec0b9ff9154dbd952c3481400118fabb744 Mon Sep 17 00:00:00 2001
22+From: Helmut Grohne <helmut.grohne@intenta.de>
33+Date: Thu, 21 Apr 2022 10:07:53 +0200
44+Subject: [PATCH] Add rudimentary support for modules property
55+66+In linux commit 6dd85ff178cd76851e2184b13e545f5a88d1be30, Linux Torvalds
77+changed "option modules" to plain "modules" since it was the only option
88+left. kconfiglib does not have much support for either besides parsing
99+it and suppressing warnings when it is applied to the 'MODULES' symbol.
1010+Mirror this behaviour for the newer "modules" property.
1111+1212+Fixes: #106
1313+---
1414+ kconfiglib.py | 14 ++++++++++++++
1515+ 1 file changed, 14 insertions(+)
1616+1717+diff --git a/kconfiglib.py b/kconfiglib.py
1818+index c67895c..ccef123 100644
1919+--- a/kconfiglib.py
2020++++ b/kconfiglib.py
2121+@@ -3263,6 +3263,20 @@ def _parse_props(self, node):
2222+ else:
2323+ self._parse_error("unrecognized option")
2424+2525++ elif t0 is _T_MODULES:
2626++ # 'modules' formerly was 'option modules'. See above for why
2727++ # and when it is ignored. It was changed in
2828++ # linux commit 6dd85ff178cd76851e2184b13e545f5a88d1be30.
2929++ if node.item is not self.modules:
3030++ self._warn("the 'modules' property is not supported. Let "
3131++ "me know if this is a problem for you, as it "
3232++ "wouldn't be that hard to implement. Note that "
3333++ "modules are supported -- Kconfiglib just "
3434++ "assumes the symbol name MODULES, like older "
3535++ "versions of the C implementation did when "
3636++ "'modules' wasn't used.",
3737++ self.filename, self.linenr)
3838++
3939+ elif t0 is _T_OPTIONAL:
4040+ if node.item.__class__ is not Choice:
4141+ self._parse_error('"optional" is only valid for choices')
···1414 sha256 = "0g690bk789hsry34y4ahvly5c8w8imca90ss4njfqf7m2qicrlmy";
1515 };
16161717+ patches = [
1818+ # see https://github.com/ulfalizer/Kconfiglib/pull/119
1919+ ./0001-Add-rudimentary-support-for-modules-property.patch
2020+ ];
2121+1722 # doesnt work out of the box but might be possible
1823 doCheck = false;
1924
···11+From 6b3ab4a94e4d498cdabd5aac6b749031abd785c8 Mon Sep 17 00:00:00 2001
22+From: Ralph Meijer <ralphm@ik.nu>
33+Date: Thu, 18 Jul 2024 19:04:47 +0200
44+Subject: [PATCH] Remove py2 compat
55+66+Co-authored-by: OPNA2608 <opna2608@protonmail.com>
77+---
88+ setup.py | 11 ++-
99+ wokkel/component.py | 13 ++-
1010+ wokkel/data_form.py | 70 ++++++----------
1111+ wokkel/delay.py | 2 +-
1212+ wokkel/disco.py | 51 ++++++------
1313+ wokkel/formats.py | 20 ++---
1414+ wokkel/generic.py | 19 +----
1515+ wokkel/iwokkel.py | 150 +++++++++++++++++-----------------
1616+ wokkel/muc.py | 67 ++++++++-------
1717+ wokkel/pubsub.py | 55 ++++++-------
1818+ wokkel/server.py | 17 ++--
1919+ wokkel/shim.py | 5 +-
2020+ wokkel/subprotocols.py | 13 ++-
2121+ wokkel/test/helpers.py | 5 +-
2222+ wokkel/test/test_client.py | 3 +-
2323+ wokkel/test/test_data_form.py | 89 +++++---------------
2424+ wokkel/test/test_generic.py | 75 +----------------
2525+ wokkel/test/test_muc.py | 13 ++-
2626+ wokkel/test/test_server.py | 6 +-
2727+ wokkel/test/test_shim.py | 5 +-
2828+ wokkel/test/test_xmppim.py | 19 ++---
2929+ wokkel/xmppim.py | 89 ++++++++++----------
3030+ 22 files changed, 318 insertions(+), 479 deletions(-)
3131+3232+diff --git a/setup.py b/setup.py
3333+index 8804fd9..f7f1e33 100755
3434+--- a/setup.py
3535++++ b/setup.py
3636+@@ -40,11 +40,11 @@ setup(name='wokkel',
3737+ license='MIT',
3838+ platforms='any',
3939+ classifiers=[
4040+- 'Programming Language :: Python :: 2.7',
4141+ 'Programming Language :: Python :: 3',
4242+- 'Programming Language :: Python :: 3.4',
4343+- 'Programming Language :: Python :: 3.5',
4444+ 'Programming Language :: Python :: 3.6',
4545++ 'Programming Language :: Python :: 3.7',
4646++ 'Programming Language :: Python :: 3.8',
4747++ 'Programming Language :: Python :: 3.9',
4848+ ],
4949+ packages=[
5050+ 'wokkel',
5151+@@ -60,16 +60,15 @@ setup(name='wokkel',
5252+ install_requires=[
5353+ 'incremental>=16.9.0',
5454+ 'python-dateutil',
5555++ 'Twisted[tls]>=16.4.0',
5656+ ],
5757+ extras_require={
5858+- ":python_version<'3'": 'Twisted[tls]>=15.5.0',
5959+- ":python_version>'3'": 'Twisted[tls]>=16.4.0',
6060+ "dev": [
6161+ "pyflakes",
6262+ "coverage",
6363++ "pydoctor",
6464+ "sphinx",
6565+ "towncrier",
6666+ ],
6767+- "dev:python_version<'3'": "pydoctor",
6868+ },
6969+ )
7070+diff --git a/wokkel/component.py b/wokkel/component.py
7171+index da48230..9410837 100644
7272+--- a/wokkel/component.py
7373++++ b/wokkel/component.py
7474+@@ -12,7 +12,6 @@ from __future__ import division, absolute_import
7575+ from twisted.application import service
7676+ from twisted.internet import reactor
7777+ from twisted.python import log
7878+-from twisted.python.compat import unicode
7979+ from twisted.words.protocols.jabber.jid import internJID as JID
8080+ from twisted.words.protocols.jabber import component, error, xmlstream
8181+ from twisted.words.xish import domish
8282+@@ -105,7 +104,7 @@ class InternalComponent(xmlstream.XMPPHandlerCollection, service.Service):
8383+ components of this type connect to a router in the same process. This
8484+ allows for one-process XMPP servers.
8585+8686+- @ivar domains: Domains (as L{unicode}) this component will handle traffic
8787++ @ivar domains: Domains (as L{str}) this component will handle traffic
8888+ for.
8989+ @type domains: L{set}
9090+ """
9191+@@ -177,7 +176,7 @@ class ListenComponentAuthenticator(xmlstream.ListenAuthenticator):
9292+ Authenticator for accepting components.
9393+9494+ @ivar secret: The shared used to authorized incoming component connections.
9595+- @type secret: L{unicode}.
9696++ @type secret: L{str}.
9797+ """
9898+9999+ namespace = NS_COMPONENT_ACCEPT
100100+@@ -241,7 +240,7 @@ class ListenComponentAuthenticator(xmlstream.ListenAuthenticator):
101101+ L{onHandshake}.
102102+ """
103103+ if (element.uri, element.name) == (self.namespace, 'handshake'):
104104+- self.onHandshake(unicode(element))
105105++ self.onHandshake(str(element))
106106+ else:
107107+ exc = error.StreamError('not-authorized')
108108+ self.xmlstream.sendStreamError(exc)
109109+@@ -257,7 +256,7 @@ class ListenComponentAuthenticator(xmlstream.ListenAuthenticator):
110110+ be exchanged.
111111+ """
112112+ calculatedHash = xmlstream.hashPassword(self.xmlstream.sid,
113113+- unicode(self.secret))
114114++ str(self.secret))
115115+ if handshake != calculatedHash:
116116+ exc = error.StreamError('not-authorized', text='Invalid hash')
117117+ self.xmlstream.sendStreamError(exc)
118118+@@ -301,7 +300,7 @@ class Router(object):
119119+120120+ @param destination: Destination of the route to be added as a host name
121121+ or L{None} for the default route.
122122+- @type destination: L{unicode} or L{NoneType}
123123++ @type destination: L{str} or L{NoneType}
124124+125125+ @param xs: XML Stream to register the route for.
126126+ @type xs:
127127+@@ -316,7 +315,7 @@ class Router(object):
128128+ Remove a route.
129129+130130+ @param destination: Destination of the route that should be removed.
131131+- @type destination: L{unicode}
132132++ @type destination: L{str}
133133+134134+ @param xs: XML Stream to remove the route for.
135135+ @type xs:
136136+diff --git a/wokkel/data_form.py b/wokkel/data_form.py
137137+index ed9c5fc..7f1c34c 100644
138138+--- a/wokkel/data_form.py
139139++++ b/wokkel/data_form.py
140140+@@ -17,7 +17,6 @@ from __future__ import division, absolute_import
141141+ from zope.interface import implementer
142142+ from zope.interface.common import mapping
143143+144144+-from twisted.python.compat import iteritems, unicode, _PY3
145145+ from twisted.words.protocols.jabber.jid import JID
146146+ from twisted.words.xish import domish
147147+148148+@@ -51,9 +50,9 @@ class Option(object):
149149+ Data Forms field option.
150150+151151+ @ivar value: Value of this option.
152152+- @type value: L{unicode}
153153++ @type value: L{str}
154154+ @ivar label: Optional label for this option.
155155+- @type label: L{unicode} or L{NoneType}
156156++ @type label: L{str} or L{NoneType}
157157+ """
158158+159159+ def __init__(self, value, label=None):
160160+@@ -91,7 +90,7 @@ class Option(object):
161161+ raise Error("Option has no value")
162162+163163+ label = element.getAttribute('label')
164164+- return Option(unicode(valueElements[0]), label)
165165++ return Option(str(valueElements[0]), label)
166166+167167+168168+ class Field(object):
169169+@@ -108,15 +107,15 @@ class Field(object):
170170+ @ivar var: Field name. Optional if C{fieldType} is C{'fixed'}.
171171+ @type var: L{str}
172172+ @ivar label: Human readable label for this field.
173173+- @type label: L{unicode}
174174++ @type label: L{str}
175175+ @ivar values: The values for this field, for multi-valued field
176176+- types, as a list of L{bool}, L{unicode} or L{JID}.
177177++ types, as a list of L{bool}, L{str} or L{JID}.
178178+ @type values: L{list}
179179+ @ivar options: List of possible values to choose from in a response
180180+ to this form as a list of L{Option}s.
181181+ @type options: L{list}
182182+ @ivar desc: Human readable description for this field.
183183+- @type desc: L{unicode}
184184++ @type desc: L{str}
185185+ @ivar required: Whether the field is required to be provided in a
186186+ response to this form.
187187+ @type required: L{bool}
188188+@@ -147,7 +146,7 @@ class Field(object):
189189+ try:
190190+ self.options = [Option(optionValue, optionLabel)
191191+ for optionValue, optionLabel
192192+- in iteritems(options)]
193193++ in options.items()]
194194+ except AttributeError:
195195+ self.options = options or []
196196+197197+@@ -185,7 +184,7 @@ class Field(object):
198198+199199+ Sets C{value} as the only element of L{values}.
200200+201201+- @type value: L{bool}, L{unicode} or L{JID}
202202++ @type value: L{bool}, L{str} or L{JID}
203203+ """
204204+ self.values = [value]
205205+206206+@@ -229,7 +228,7 @@ class Field(object):
207207+ newValues = []
208208+ for value in self.values:
209209+ if self.fieldType == 'boolean':
210210+- if isinstance(value, (str, unicode)):
211211++ if isinstance(value, str):
212212+ checkValue = value.lower()
213213+ if not checkValue in ('0', '1', 'false', 'true'):
214214+ raise ValueError("Not a boolean")
215215+@@ -263,9 +262,9 @@ class Field(object):
216216+217217+ for value in self.values:
218218+ if isinstance(value, bool):
219219+- value = unicode(value).lower()
220220++ value = str(value).lower()
221221+ else:
222222+- value = unicode(value)
223223++ value = str(value)
224224+225225+ field.addElement('value', content=value)
226226+227227+@@ -288,7 +287,7 @@ class Field(object):
228228+229229+ @staticmethod
230230+ def _parse_desc(field, element):
231231+- desc = unicode(element)
232232++ desc = str(element)
233233+ if desc:
234234+ field.desc = desc
235235+236236+@@ -305,7 +304,7 @@ class Field(object):
237237+238238+ @staticmethod
239239+ def _parse_value(field, element):
240240+- value = unicode(element)
241241++ value = str(element)
242242+ field.values.append(value)
243243+244244+245245+@@ -313,9 +312,9 @@ class Field(object):
246246+ def fromElement(element):
247247+ field = Field(None)
248248+249249+- for eAttr, fAttr in iteritems({'type': 'fieldType',
250250+- 'var': 'var',
251251+- 'label': 'label'}):
252252++ for eAttr, fAttr in {'type': 'fieldType',
253253++ 'var': 'var',
254254++ 'label': 'label'}.items():
255255+ value = element.getAttribute(eAttr)
256256+ if value:
257257+ setattr(field, fAttr, value)
258258+@@ -350,7 +349,7 @@ class Field(object):
259259+260260+ if 'options' in fieldDict:
261261+ options = []
262262+- for value, label in iteritems(fieldDict['options']):
263263++ for value, label in fieldDict['options'].items():
264264+ options.append(Option(value, label))
265265+ kwargs['options'] = options
266266+267267+@@ -385,9 +384,9 @@ class Form(object):
268268+ @type formType: L{str}
269269+270270+ @ivar title: Natural language title of the form.
271271+- @type title: L{unicode}
272272++ @type title: L{str}
273273+274274+- @ivar instructions: Natural language instructions as a list of L{unicode}
275275++ @ivar instructions: Natural language instructions as a list of L{str}
276276+ strings without line breaks.
277277+ @type instructions: L{list}
278278+279279+@@ -497,7 +496,7 @@ class Form(object):
280280+ C{fieldDefs}.
281281+ @type filterUnknown: L{bool}
282282+ """
283283+- for name, value in iteritems(values):
284284++ for name, value in values.items():
285285+ fieldDict = {'var': name,
286286+ 'type': None}
287287+288288+@@ -542,14 +541,14 @@ class Form(object):
289289+290290+ @staticmethod
291291+ def _parse_title(form, element):
292292+- title = unicode(element)
293293++ title = str(element)
294294+ if title:
295295+ form.title = title
296296+297297+298298+ @staticmethod
299299+ def _parse_instructions(form, element):
300300+- instructions = unicode(element)
301301++ instructions = str(element)
302302+ if instructions:
303303+ form.instructions.append(instructions)
304304+305305+@@ -624,36 +623,19 @@ class Form(object):
306306+ return key in self.fields
307307+308308+309309+- def iterkeys(self):
310310++ def keys(self):
311311+ return iter(self)
312312+313313+314314+- def itervalues(self):
315315++ def values(self):
316316+ for key in self:
317317+ yield self[key]
318318+319319+320320+- def iteritems(self):
321321++ def items(self):
322322+ for key in self:
323323+ yield (key, self[key])
324324+325325+- if _PY3:
326326+- keys = iterkeys
327327+- values = itervalues
328328+- items = iteritems
329329+- else:
330330+- def keys(self):
331331+- return list(self)
332332+-
333333+-
334334+- def values(self):
335335+- return list(self.itervalues())
336336+-
337337+-
338338+- def items(self):
339339+- return list(self.iteritems())
340340+-
341341+-
342342+ def getValues(self):
343343+ """
344344+ Extract values from the named form fields.
345345+@@ -701,7 +683,7 @@ class Form(object):
346346+347347+ filtered = []
348348+349349+- for name, field in iteritems(self.fields):
350350++ for name, field in self.fields.items():
351351+ if name in fieldDefs:
352352+ fieldDef = fieldDefs[name]
353353+ if 'type' not in fieldDef:
354354+diff --git a/wokkel/delay.py b/wokkel/delay.py
355355+index be06cb3..1dd1703 100644
356356+--- a/wokkel/delay.py
357357++++ b/wokkel/delay.py
358358+@@ -46,7 +46,7 @@ class Delay(object):
359359+ Render this instance into a domish Element.
360360+361361+ @param legacy: If C{True}, use the legacy XEP-0091 format.
362362+- @type legacy: C{bool}
363363++ @type legacy: L{bool}
364364+ """
365365+ if not self.stamp:
366366+ raise ValueError("stamp is required")
367367+diff --git a/wokkel/disco.py b/wokkel/disco.py
368368+index 9ea43ef..227789d 100644
369369+--- a/wokkel/disco.py
370370++++ b/wokkel/disco.py
371371+@@ -13,7 +13,6 @@ U{XEP-0030<http://xmpp.org/extensions/xep-0030.html>}.
372372+ from __future__ import division, absolute_import
373373+374374+ from twisted.internet import defer
375375+-from twisted.python.compat import iteritems, unicode
376376+ from twisted.words.protocols.jabber import error, jid
377377+ from twisted.words.xish import domish
378378+379379+@@ -29,11 +28,11 @@ IQ_GET = '/iq[@type="get"]'
380380+ DISCO_INFO = IQ_GET + '/query[@xmlns="' + NS_DISCO_INFO + '"]'
381381+ DISCO_ITEMS = IQ_GET + '/query[@xmlns="' + NS_DISCO_ITEMS + '"]'
382382+383383+-class DiscoFeature(unicode):
384384++class DiscoFeature(str):
385385+ """
386386+ XMPP service discovery feature.
387387+388388+- This extends C{unicode} to convert to and from L{domish.Element}, but
389389++ This extends L{str} to convert to and from L{domish.Element}, but
390390+ further behaves identically.
391391+ """
392392+393393+@@ -44,7 +43,7 @@ class DiscoFeature(unicode):
394394+ @rtype: L{domish.Element}.
395395+ """
396396+ element = domish.Element((NS_DISCO_INFO, 'feature'))
397397+- element['var'] = unicode(self)
398398++ element['var'] = str(self)
399399+ return element
400400+401401+402402+@@ -68,11 +67,11 @@ class DiscoIdentity(object):
403403+ XMPP service discovery identity.
404404+405405+ @ivar category: The identity category.
406406+- @type category: C{unicode}
407407++ @type category: L{str}
408408+ @ivar type: The identity type.
409409+- @type type: C{unicode}
410410++ @type type: L{str}
411411+ @ivar name: The optional natural language name for this entity.
412412+- @type name: C{unicode}
413413++ @type name: L{str}
414414+ """
415415+416416+ def __init__(self, category, idType, name=None):
417417+@@ -119,21 +118,21 @@ class DiscoInfo(object):
418418+ XMPP service discovery info.
419419+420420+ @ivar nodeIdentifier: The optional node this info applies to.
421421+- @type nodeIdentifier: C{unicode}
422422++ @type nodeIdentifier: L{str}
423423+ @ivar features: Features as L{DiscoFeature}.
424424+- @type features: C{set}
425425++ @type features: L{set}
426426+ @ivar identities: Identities as a mapping from (category, type) to name,
427427+- all C{unicode}.
428428+- @type identities: C{dict}
429429++ all L{str}.
430430++ @type identities: L{dict}
431431+ @ivar extensions: Service discovery extensions as a mapping from the
432432+- extension form's C{FORM_TYPE} (C{unicode}) to
433433++ extension form's C{FORM_TYPE} (L{str}) to
434434+ L{data_form.Form}. Forms with no C{FORM_TYPE} field
435435+ are mapped as C{None}. Note that multiple forms
436436+ with the same C{FORM_TYPE} have the last in sequence
437437+ prevail.
438438+- @type extensions: C{dict}
439439++ @type extensions: L{dict}
440440+ @ivar _items: Sequence of added items.
441441+- @type _items: C{list}
442442++ @type _items: L{list}
443443+ """
444444+445445+ def __init__(self):
446446+@@ -226,9 +225,9 @@ class DiscoItem(object):
447447+ @ivar entity: The entity holding the item.
448448+ @type entity: L{jid.JID}
449449+ @ivar nodeIdentifier: The optional node identifier for the item.
450450+- @type nodeIdentifier: C{unicode}
451451++ @type nodeIdentifier: L{str}
452452+ @ivar name: The optional natural language name for this entity.
453453+- @type name: C{unicode}
454454++ @type name: L{str}
455455+ """
456456+457457+ def __init__(self, entity, nodeIdentifier='', name=None):
458458+@@ -278,9 +277,9 @@ class DiscoItems(object):
459459+ XMPP service discovery items.
460460+461461+ @ivar nodeIdentifier: The optional node this info applies to.
462462+- @type nodeIdentifier: C{unicode}
463463++ @type nodeIdentifier: L{str}
464464+ @ivar _items: Sequence of added items.
465465+- @type _items: C{list}
466466++ @type _items: L{list}
467467+ """
468468+469469+ def __init__(self):
470470+@@ -353,9 +352,9 @@ class _DiscoRequest(generic.Request):
471471+ A Service Discovery request.
472472+473473+ @ivar verb: Type of request: C{'info'} or C{'items'}.
474474+- @type verb: C{str}
475475++ @type verb: L{str}
476476+ @ivar nodeIdentifier: Optional node to request info for.
477477+- @type nodeIdentifier: C{unicode}
478478++ @type nodeIdentifier: L{str}
479479+ """
480480+481481+ verb = None
482482+@@ -366,7 +365,7 @@ class _DiscoRequest(generic.Request):
483483+ NS_DISCO_ITEMS: 'items',
484484+ }
485485+486486+- _verbRequestMap = dict(((v, k) for k, v in iteritems(_requestVerbMap)))
487487++ _verbRequestMap = dict(((v, k) for k, v in _requestVerbMap.items()))
488488+489489+ def __init__(self, verb=None, nodeIdentifier='',
490490+ recipient=None, sender=None):
491491+@@ -415,7 +414,7 @@ class DiscoClientProtocol(XMPPHandler):
492492+ @type entity: L{jid.JID}
493493+494494+ @param nodeIdentifier: Optional node to request info from.
495495+- @type nodeIdentifier: C{unicode}
496496++ @type nodeIdentifier: L{str}
497497+498498+ @param sender: Optional sender address.
499499+ @type sender: L{jid.JID}
500500+@@ -438,7 +437,7 @@ class DiscoClientProtocol(XMPPHandler):
501501+ @type entity: L{jid.JID}
502502+503503+ @param nodeIdentifier: Optional node to request info from.
504504+- @type nodeIdentifier: C{unicode}
505505++ @type nodeIdentifier: L{str}
506506+507507+ @param sender: Optional sender address.
508508+ @type sender: L{jid.JID}
509509+@@ -534,7 +533,7 @@ class DiscoHandler(XMPPHandler, IQHandlerMixin):
510510+511511+ @param deferredList: List of deferreds for which the results should be
512512+ gathered.
513513+- @type deferredList: C{list}
514514++ @type deferredList: L{list}
515515+ @return: Deferred that fires with a list of gathered results.
516516+ @rtype: L{defer.Deferred}
517517+ """
518518+@@ -566,7 +565,7 @@ class DiscoHandler(XMPPHandler, IQHandlerMixin):
519519+ @param target: The entity the request was sent to.
520520+ @type target: L{JID<twisted.words.protocols.jabber.jid.JID>}
521521+ @param nodeIdentifier: The optional node being queried, or C{''}.
522522+- @type nodeIdentifier: C{unicode}
523523++ @type nodeIdentifier: L{str}
524524+ @return: Deferred with the gathered results from sibling handlers.
525525+ @rtype: L{defer.Deferred}
526526+ """
527527+@@ -589,7 +588,7 @@ class DiscoHandler(XMPPHandler, IQHandlerMixin):
528528+ @param target: The entity the request was sent to.
529529+ @type target: L{JID<twisted.words.protocols.jabber.jid.JID>}
530530+ @param nodeIdentifier: The optional node being queried, or C{''}.
531531+- @type nodeIdentifier: C{unicode}
532532++ @type nodeIdentifier: L{str}
533533+ @return: Deferred with the gathered results from sibling handlers.
534534+ @rtype: L{defer.Deferred}
535535+ """
536536+diff --git a/wokkel/formats.py b/wokkel/formats.py
537537+index 0eb0be6..972cc7e 100644
538538+--- a/wokkel/formats.py
539539++++ b/wokkel/formats.py
540540+@@ -9,8 +9,6 @@ Generic payload formats.
541541+542542+ from __future__ import division, absolute_import
543543+544544+-from twisted.python.compat import unicode
545545+-
546546+ NS_MOOD = 'http://jabber.org/protocol/mood'
547547+ NS_TUNE = 'http://jabber.org/protocol/tune'
548548+549549+@@ -55,7 +53,7 @@ class Mood:
550550+ continue
551551+552552+ if child.name == 'text':
553553+- text = unicode(child)
554554++ text = str(child)
555555+ else:
556556+ value = child.name
557557+558558+@@ -76,19 +74,19 @@ class Tune:
559559+ U{XEP-0118<http://xmpp.org/extensions/xep-0118.html>}.
560560+561561+ @ivar artist: The artist or performer of the song or piece.
562562+- @type artist: C{unicode}
563563++ @type artist: L{str}
564564+ @ivar length: The duration of the song or piece in seconds.
565565+- @type length: C{int}
566566++ @type length: L{int}
567567+ @ivar source: The collection (e.g. album) or other source.
568568+- @type source: C{unicode}
569569++ @type source: L{str}
570570+ @ivar title: The title of the song or piece
571571+- @type title: C{unicode}
572572++ @type title: L{str}
573573+ @ivar track: A unique identifier for the tune; e.g. the track number within
574574+ the collection or the specific URI for the object.
575575+- @type track: C{unicode}
576576++ @type track: L{str}
577577+ @ivar uri: A URI pointing to information about the song, collection, or
578578+ artist.
579579+- @type uri: C{str}
580580++ @type uri: L{str}
581581+582582+ """
583583+584584+@@ -122,10 +120,10 @@ class Tune:
585585+ continue
586586+587587+ if child.name in ('artist', 'source', 'title', 'track', 'uri'):
588588+- setattr(tune, child.name, unicode(child))
589589++ setattr(tune, child.name, str(child))
590590+ elif child.name == 'length':
591591+ try:
592592+- tune.length = int(unicode(child))
593593++ tune.length = int(str(child))
594594+ except ValueError:
595595+ pass
596596+597597+diff --git a/wokkel/generic.py b/wokkel/generic.py
598598+index 2e975f6..becff8f 100644
599599+--- a/wokkel/generic.py
600600++++ b/wokkel/generic.py
601601+@@ -13,14 +13,11 @@ from zope.interface import implementer
602602+603603+ from twisted.internet import defer, protocol
604604+ from twisted.python import reflect
605605+-from twisted.python.deprecate import deprecated
606606+ from twisted.words.protocols.jabber import error, jid, xmlstream
607607+ from twisted.words.protocols.jabber.xmlstream import toResponse
608608+ from twisted.words.xish import domish, utility
609609+ from twisted.words.xish.xmlstream import BootstrapMixin
610610+611611+-from incremental import Version
612612+-
613613+ from wokkel.iwokkel import IDisco
614614+ from wokkel.subprotocols import XMPPHandler
615615+616616+@@ -35,7 +32,7 @@ def parseXml(string):
617617+ Parse serialized XML into a DOM structure.
618618+619619+ @param string: The serialized XML to be parsed, UTF-8 encoded.
620620+- @type string: C{str}.
621621++ @type string: L{str}.
622622+ @return: The DOM structure, or C{None} on empty or incomplete input.
623623+ @rtype: L{domish.Element}
624624+ """
625625+@@ -332,17 +329,3 @@ class DeferredXmlStreamFactory(BootstrapMixin, protocol.ClientFactory):
626626+627627+ def clientConnectionFailed(self, connector, reason):
628628+ self.deferred.errback(reason)
629629+-
630630+-
631631+-
632632+-@deprecated(Version("wokkel", 18, 0, 0), "unicode.encode('idna')")
633633+-def prepareIDNName(name):
634634+- """
635635+- Encode a unicode IDN Domain Name into its ACE equivalent.
636636+-
637637+- This will encode the domain labels, separated by allowed dot code points,
638638+- to their ASCII Compatible Encoding (ACE) equivalent, using punycode. The
639639+- result is an ASCII byte string of the encoded labels, separated by the
640640+- standard full stop.
641641+- """
642642+- return name.encode('idna')
643643+diff --git a/wokkel/iwokkel.py b/wokkel/iwokkel.py
644644+index 30a1057..35383b5 100644
645645+--- a/wokkel/iwokkel.py
646646++++ b/wokkel/iwokkel.py
647647+@@ -46,7 +46,7 @@ class IDisco(Interface):
648648+ @param nodeIdentifier: The optional identifier of the node at this
649649+ entity to retrieve the identify and features of. The default is
650650+ C{''}, meaning the root node.
651651+- @type nodeIdentifier: C{unicode}
652652++ @type nodeIdentifier: L{str}
653653+ """
654654+655655+ def getDiscoItems(requestor, target, nodeIdentifier=''):
656656+@@ -60,7 +60,7 @@ class IDisco(Interface):
657657+ @param nodeIdentifier: The optional identifier of the node at this
658658+ entity to retrieve the identify and features of.
659659+ The default is C{''}, meaning the root node.
660660+- @type nodeIdentifier: C{unicode}
661661++ @type nodeIdentifier: L{str}
662662+ """
663663+664664+665665+@@ -109,7 +109,7 @@ class IPubSubClient(Interface):
666666+ @param nodeIdentifier: Optional suggestion for the new node's
667667+ identifier. If omitted, the creation of an
668668+ instant node will be attempted.
669669+- @type nodeIdentifier: C{unicode}
670670++ @type nodeIdentifier: L{str}
671671+ @return: a deferred that fires with the identifier of the newly created
672672+ node. Note that this can differ from the suggested identifier
673673+ if the publish subscribe service chooses to modify or ignore
674674+@@ -124,7 +124,7 @@ class IPubSubClient(Interface):
675675+ @param service: The publish-subscribe service entity.
676676+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
677677+ @param nodeIdentifier: Identifier of the node to be deleted.
678678+- @type nodeIdentifier: C{unicode}
679679++ @type nodeIdentifier: L{str}
680680+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
681681+ """
682682+683683+@@ -135,7 +135,7 @@ class IPubSubClient(Interface):
684684+ @param service: The publish-subscribe service entity.
685685+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
686686+ @param nodeIdentifier: Identifier of the node to subscribe to.
687687+- @type nodeIdentifier: C{unicode}
688688++ @type nodeIdentifier: L{str}
689689+ @param subscriber: JID to subscribe to the node.
690690+ @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
691691+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
692692+@@ -148,7 +148,7 @@ class IPubSubClient(Interface):
693693+ @param service: The publish-subscribe service entity.
694694+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
695695+ @param nodeIdentifier: Identifier of the node to unsubscribe from.
696696+- @type nodeIdentifier: C{unicode}
697697++ @type nodeIdentifier: L{str}
698698+ @param subscriber: JID to unsubscribe from the node.
699699+ @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
700700+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
701701+@@ -165,9 +165,9 @@ class IPubSubClient(Interface):
702702+ @param service: The publish-subscribe service entity.
703703+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
704704+ @param nodeIdentifier: Identifier of the node to publish to.
705705+- @type nodeIdentifier: C{unicode}
706706++ @type nodeIdentifier: L{str}
707707+ @param items: List of item elements.
708708+- @type items: C{list} of L{Item}
709709++ @type items: L{list} of L{Item}
710710+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
711711+ """
712712+713713+@@ -191,12 +191,12 @@ class IPubSubService(Interface):
714714+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
715715+ @param nodeIdentifier: The identifier of the node that was published
716716+ to.
717717+- @type nodeIdentifier: C{unicode}
718718++ @type nodeIdentifier: L{str}
719719+ @param notifications: The notifications as tuples of subscriber, the
720720+ list of subscriptions and the list of items to be notified.
721721+- @type notifications: C{list} of
722722+- (L{JID<twisted.words.protocols.jabber.jid.JID>}, C{list} of
723723+- L{Subscription<wokkel.pubsub.Subscription>}, C{list} of
724724++ @type notifications: L{list} of
725725++ (L{JID<twisted.words.protocols.jabber.jid.JID>}, L{list} of
726726++ L{Subscription<wokkel.pubsub.Subscription>}, L{list} of
727727+ L{Element<twisted.words.xish.domish.Element>})
728728+ """
729729+730730+@@ -209,14 +209,14 @@ class IPubSubService(Interface):
731731+ @param service: The entity the notifications will originate from.
732732+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
733733+ @param nodeIdentifier: The identifier of the node that was deleted.
734734+- @type nodeIdentifier: C{unicode}
735735++ @type nodeIdentifier: L{str}
736736+ @param subscribers: The subscribers for which a notification should be
737737+ sent out.
738738+- @type subscribers: C{list} of
739739++ @type subscribers: L{list} of
740740+ L{JID<twisted.words.protocols.jabber.jid.JID>}
741741+ @param redirectURI: Optional XMPP URI of another node that subscribers
742742+ are redirected to.
743743+- @type redirectURI: C{str}
744744++ @type redirectURI: L{str}
745745+ """
746746+747747+ def publish(requestor, service, nodeIdentifier, items):
748748+@@ -228,9 +228,9 @@ class IPubSubService(Interface):
749749+ @param service: The entity the request was addressed to.
750750+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
751751+ @param nodeIdentifier: The identifier of the node to publish to.
752752+- @type nodeIdentifier: C{unicode}
753753++ @type nodeIdentifier: L{str}
754754+ @param items: The items to be published as elements.
755755+- @type items: C{list} of C{Element<twisted.words.xish.domish.Element>}
756756++ @type items: L{list} of C{Element<twisted.words.xish.domish.Element>}
757757+ @return: deferred that fires on success.
758758+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
759759+ """
760760+@@ -244,7 +244,7 @@ class IPubSubService(Interface):
761761+ @param service: The entity the request was addressed to.
762762+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
763763+ @param nodeIdentifier: The identifier of the node to subscribe to.
764764+- @type nodeIdentifier: C{unicode}
765765++ @type nodeIdentifier: L{str}
766766+ @param subscriber: The entity to be subscribed.
767767+ @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
768768+ @return: A deferred that fires with a
769769+@@ -261,7 +261,7 @@ class IPubSubService(Interface):
770770+ @param service: The entity the request was addressed to.
771771+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
772772+ @param nodeIdentifier: The identifier of the node to unsubscribe from.
773773+- @type nodeIdentifier: C{unicode}
774774++ @type nodeIdentifier: L{str}
775775+ @param subscriber: The entity to be unsubscribed.
776776+ @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
777777+ @return: A deferred that fires with C{None} when unsubscription has
778778+@@ -277,7 +277,7 @@ class IPubSubService(Interface):
779779+ @type requestor: L{JID<twisted.words.protocols.jabber.jid.JID>}
780780+ @param service: The entity the request was addressed to.
781781+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
782782+- @return: A deferred that fires with a C{list} of subscriptions as
783783++ @return: A deferred that fires with a L{list} of subscriptions as
784784+ L{Subscription<wokkel.pubsub.Subscription>}.
785785+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
786786+ """
787787+@@ -290,9 +290,9 @@ class IPubSubService(Interface):
788788+ @type requestor: L{JID<twisted.words.protocols.jabber.jid.JID>}
789789+ @param service: The entity the request was addressed to.
790790+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
791791+- @return: A deferred that fires with a C{list} of affiliations as
792792+- C{tuple}s of (node identifier as C{unicode}, affiliation state as
793793+- C{str}). The affiliation can be C{'owner'}, C{'publisher'}, or
794794++ @return: A deferred that fires with a L{list} of affiliations as
795795++ C{tuple}s of (node identifier as L{str}, affiliation state as
796796++ L{str}). The affiliation can be C{'owner'}, C{'publisher'}, or
797797+ C{'outcast'}.
798798+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
799799+ """
800800+@@ -308,8 +308,8 @@ class IPubSubService(Interface):
801801+ @param nodeIdentifier: The suggestion for the identifier of the node
802802+ to be created. If the request did not include a suggestion for the
803803+ node identifier, the value is C{None}.
804804+- @type nodeIdentifier: C{unicode} or C{NoneType}
805805+- @return: A deferred that fires with a C{unicode} that represents
806806++ @type nodeIdentifier: L{str} or C{NoneType}
807807++ @return: A deferred that fires with a L{str} that represents
808808+ the identifier of the new node.
809809+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
810810+ """
811811+@@ -322,10 +322,10 @@ class IPubSubService(Interface):
812812+ by option name. The value of each entry represents the specifics for
813813+ that option in a dictionary:
814814+815815+- - C{'type'} (C{str}): The option's type (see
816816++ - C{'type'} (L{str}): The option's type (see
817817+ L{Field<wokkel.data_form.Field>}'s doc string for possible values).
818818+- - C{'label'} (C{unicode}): A human readable label for this option.
819819+- - C{'options'} (C{dict}): Optional list of possible values for this
820820++ - C{'label'} (L{str}): A human readable label for this option.
821821++ - C{'options'} (L{dict}): Optional list of possible values for this
822822+ option.
823823+824824+ Example::
825825+@@ -346,7 +346,7 @@ class IPubSubService(Interface):
826826+ }
827827+ }
828828+829829+- @rtype: C{dict}.
830830++ @rtype: L{dict}.
831831+ """
832832+833833+ def getDefaultConfiguration(requestor, service, nodeType):
834834+@@ -359,11 +359,11 @@ class IPubSubService(Interface):
835835+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
836836+ @param nodeType: The type of node for which the configuration is
837837+ retrieved, C{'leaf'} or C{'collection'}.
838838+- @type nodeType: C{str}
839839+- @return: A deferred that fires with a C{dict} representing the default
840840+- node configuration. Keys are C{str}s that represent the
841841+- field name. Values can be of types C{unicode}, C{int} or
842842+- C{bool}.
843843++ @type nodeType: L{str}
844844++ @return: A deferred that fires with a L{dict} representing the default
845845++ node configuration. Keys are L{str}s that represent the
846846++ field name. Values can be of types L{str}, L{int} or
847847++ L{bool}.
848848+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
849849+ """
850850+851851+@@ -377,10 +377,10 @@ class IPubSubService(Interface):
852852+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
853853+ @param nodeIdentifier: The identifier of the node to retrieve the
854854+ configuration from.
855855+- @type nodeIdentifier: C{unicode}
856856+- @return: A deferred that fires with a C{dict} representing the node
857857+- configuration. Keys are C{str}s that represent the field name.
858858+- Values can be of types C{unicode}, C{int} or C{bool}.
859859++ @type nodeIdentifier: L{str}
860860++ @return: A deferred that fires with a L{dict} representing the node
861861++ configuration. Keys are L{str}s that represent the field name.
862862++ Values can be of types L{str}, L{int} or L{bool}.
863863+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
864864+ """
865865+866866+@@ -394,7 +394,7 @@ class IPubSubService(Interface):
867867+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
868868+ @param nodeIdentifier: The identifier of the node to change the
869869+ configuration of.
870870+- @type nodeIdentifier: C{unicode}
871871++ @type nodeIdentifier: L{str}
872872+ @return: A deferred that fires with C{None} when the node's
873873+ configuration has been changed.
874874+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
875875+@@ -410,7 +410,7 @@ class IPubSubService(Interface):
876876+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
877877+ @param nodeIdentifier: The identifier of the node to retrieve items
878878+ from.
879879+- @type nodeIdentifier: C{unicode}
880880++ @type nodeIdentifier: L{str}
881881+ """
882882+883883+ def retract(requestor, service, nodeIdentifier, itemIdentifiers):
884884+@@ -423,7 +423,7 @@ class IPubSubService(Interface):
885885+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
886886+ @param nodeIdentifier: The identifier of the node to retract items
887887+ from.
888888+- @type nodeIdentifier: C{unicode}
889889++ @type nodeIdentifier: L{str}
890890+ """
891891+892892+ def purge(requestor, service, nodeIdentifier):
893893+@@ -435,7 +435,7 @@ class IPubSubService(Interface):
894894+ @param service: The entity the request was addressed to.
895895+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
896896+ @param nodeIdentifier: The identifier of the node to be purged.
897897+- @type nodeIdentifier: C{unicode}
898898++ @type nodeIdentifier: L{str}
899899+ """
900900+901901+ def delete(requestor, service, nodeIdentifier):
902902+@@ -447,7 +447,7 @@ class IPubSubService(Interface):
903903+ @param service: The entity the request was addressed to.
904904+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
905905+ @param nodeIdentifier: The identifier of the node to be delete.
906906+- @type nodeIdentifier: C{unicode}
907907++ @type nodeIdentifier: L{str}
908908+ """
909909+910910+911911+@@ -472,7 +472,7 @@ class IPubSubResource(Interface):
912912+ @param service: The publish-subscribe service entity.
913913+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
914914+ @param nodeIdentifier: Identifier of the node to request the info for.
915915+- @type nodeIdentifier: C{unicode}
916916++ @type nodeIdentifier: L{str}
917917+ @return: A deferred that fires with a dictionary. If not empty,
918918+ it must have the keys C{'type'} and C{'meta-data'} to keep
919919+ respectively the node type and a dictionary with the meta
920920+@@ -491,7 +491,7 @@ class IPubSubResource(Interface):
921921+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
922922+ @param nodeIdentifier: Identifier of the node to request the childs
923923+ for.
924924+- @type nodeIdentifier: C{unicode}
925925++ @type nodeIdentifier: L{str}
926926+ @return: A deferred that fires with a list of child node identifiers.
927927+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
928928+ """
929929+@@ -505,10 +505,10 @@ class IPubSubResource(Interface):
930930+ by option name. The value of each entry represents the specifics for
931931+ that option in a dictionary:
932932+933933+- - C{'type'} (C{str}): The option's type (see
934934++ - C{'type'} (L{str}): The option's type (see
935935+ L{Field<wokkel.data_form.Field>}'s doc string for possible values).
936936+- - C{'label'} (C{unicode}): A human readable label for this option.
937937+- - C{'options'} (C{dict}): Optional list of possible values for this
938938++ - C{'label'} (L{str}): A human readable label for this option.
939939++ - C{'options'} (L{dict}): Optional list of possible values for this
940940+ option.
941941+942942+ Example::
943943+@@ -529,7 +529,7 @@ class IPubSubResource(Interface):
944944+ }
945945+ }
946946+947947+- @rtype: C{dict}.
948948++ @rtype: L{dict}.
949949+ """
950950+951951+952952+@@ -574,7 +574,7 @@ class IPubSubResource(Interface):
953953+954954+ @param request: The publish-subscribe request.
955955+ @type request: L{wokkel.pubsub.PubSubRequest}
956956+- @return: A deferred that fires with a C{list} of subscriptions as
957957++ @return: A deferred that fires with a L{list} of subscriptions as
958958+ L{Subscription<wokkel.pubsub.Subscription>}.
959959+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
960960+ """
961961+@@ -586,9 +586,9 @@ class IPubSubResource(Interface):
962962+963963+ @param request: The publish-subscribe request.
964964+ @type request: L{wokkel.pubsub.PubSubRequest}
965965+- @return: A deferred that fires with a C{list} of affiliations as
966966+- C{tuple}s of (node identifier as C{unicode}, affiliation state as
967967+- C{str}). The affiliation can be C{'owner'}, C{'publisher'}, or
968968++ @return: A deferred that fires with a L{list} of affiliations as
969969++ C{tuple}s of (node identifier as L{str}, affiliation state as
970970++ L{str}). The affiliation can be C{'owner'}, C{'publisher'}, or
971971+ C{'outcast'}.
972972+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
973973+ """
974974+@@ -600,7 +600,7 @@ class IPubSubResource(Interface):
975975+976976+ @param request: The publish-subscribe request.
977977+ @type request: L{wokkel.pubsub.PubSubRequest}
978978+- @return: A deferred that fires with a C{unicode} that represents
979979++ @return: A deferred that fires with a L{str} that represents
980980+ the identifier of the new node.
981981+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
982982+ """
983983+@@ -612,10 +612,10 @@ class IPubSubResource(Interface):
984984+985985+ @param request: The publish-subscribe request.
986986+ @type request: L{wokkel.pubsub.PubSubRequest}
987987+- @return: A deferred that fires with a C{dict} representing the default
988988+- node configuration. Keys are C{str}s that represent the
989989+- field name. Values can be of types C{unicode}, C{int} or
990990+- C{bool}.
991991++ @return: A deferred that fires with a L{dict} representing the default
992992++ node configuration. Keys are L{str}s that represent the
993993++ field name. Values can be of types L{str}, L{int} or
994994++ L{bool}.
995995+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
996996+ """
997997+998998+@@ -626,9 +626,9 @@ class IPubSubResource(Interface):
999999+10001000+ @param request: The publish-subscribe request.
10011001+ @type request: L{wokkel.pubsub.PubSubRequest}
10021002+- @return: A deferred that fires with a C{dict} representing the node
10031003+- configuration. Keys are C{str}s that represent the field name.
10041004+- Values can be of types C{unicode}, C{int} or C{bool}.
10051005++ @return: A deferred that fires with a L{dict} representing the node
10061006++ configuration. Keys are L{str}s that represent the field name.
10071007++ Values can be of types L{str}, L{int} or L{bool}.
10081008+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
10091009+ """
10101010+10111011+@@ -651,7 +651,7 @@ class IPubSubResource(Interface):
10121012+10131013+ @param request: The publish-subscribe request.
10141014+ @type request: L{wokkel.pubsub.PubSubRequest}
10151015+- @return: A deferred that fires with a C{list} of L{pubsub.Item}.
10161016++ @return: A deferred that fires with a L{list} of L{pubsub.Item}.
10171017+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
10181018+ """
10191019+10201020+@@ -698,9 +698,9 @@ class IPubSubResource(Interface):
10211021+10221022+ @param request: The publish-subscribe request.
10231023+ @type request: L{wokkel.pubsub.PubSubRequest}
10241024+- @return: A deferred that fires with a C{dict} of affiliations with the
10251025++ @return: A deferred that fires with a L{dict} of affiliations with the
10261026+ entity as key (L{JID<twisted.words.protocols.jabber.jid.JID>}) and
10271027+- the affiliation state as value (C{unicode}). The affiliation can
10281028++ the affiliation state as value (L{str}). The affiliation can
10291029+ be C{u'owner'}, C{u'publisher'}, or C{u'outcast'}.
10301030+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
10311031+10321032+@@ -748,7 +748,7 @@ class IMUCClient(Interface):
10331033+ @type user: L{muc.User}
10341034+10351035+ @param subject: The subject of the given room.
10361036+- @type subject: C{unicode}
10371037++ @type subject: L{str}
10381038+ """
10391039+10401040+10411041+@@ -769,7 +769,7 @@ class IMUCClient(Interface):
10421042+10431043+ @param options: A mapping of field names to values, or C{None} to
10441044+ cancel.
10451045+- @type options: C{dict}
10461046++ @type options: L{dict}
10471047+ """
10481048+10491049+10501050+@@ -796,14 +796,14 @@ class IMUCClient(Interface):
10511051+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
10521052+10531053+ @param nick: The nick name for the entitity joining the room.
10541054+- @type nick: C{unicode}
10551055++ @type nick: L{str}
10561056+10571057+ @param historyOptions: Options for conversation history sent by the
10581058+ room upon joining.
10591059+ @type historyOptions: L{HistoryOptions}
10601060+10611061+ @param password: Optional password for the room.
10621062+- @type password: C{unicode}
10631063++ @type password: L{str}
10641064+10651065+ @return: A deferred that fires when the entity is in the room or an
10661066+ error has occurred.
10671067+@@ -820,7 +820,7 @@ class IMUCClient(Interface):
10681068+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
10691069+10701070+ @param nick: The new nick name within the room.
10711071+- @type nick: C{unicode}
10721072++ @type nick: L{str}
10731073+ """
10741074+10751075+10761076+@@ -876,7 +876,7 @@ class IMUCClient(Interface):
10771077+10781078+ @param options: A mapping of field names to values, or C{None} to
10791079+ cancel.
10801080+- @type options: C{dict}
10811081++ @type options: L{dict}
10821082+ """
10831083+10841084+10851085+@@ -890,7 +890,7 @@ class IMUCClient(Interface):
10861086+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
10871087+10881088+ @param subject: The subject you want to set.
10891089+- @type subject: C{unicode}
10901090++ @type subject: L{str}
10911091+ """
10921092+10931093+10941094+@@ -917,7 +917,7 @@ class IMUCClient(Interface):
10951095+ holding the original stanza a
10961096+ L{Element<twisted.words.xish.domish.Element>}, and C{'timestamp'}
10971097+ with the timestamp.
10981098+- @type messages: C{list} of
10991099++ @type messages: L{list} of
11001100+ L{Element<twisted.words.xish.domish.Element>}
11011101+ """
11021102+11031103+@@ -933,7 +933,7 @@ class IMUCClient(Interface):
11041104+ @type entity: L{JID<twisted.words.protocols.jabber.jid.JID>}
11051105+11061106+ @param reason: The reason for banning the entity.
11071107+- @type reason: C{unicode}
11081108++ @type reason: L{str}
11091109+11101110+ @param sender: The entity sending the request.
11111111+ @type sender: L{JID<twisted.words.protocols.jabber.jid.JID>}
11121112+@@ -949,10 +949,10 @@ class IMUCClient(Interface):
11131113+11141114+ @param nick: The occupant to be banned.
11151115+ @type nick: L{JID<twisted.words.protocols.jabber.jid.JID>} or
11161116+- C{unicode}
11171117++ L{str}
11181118+11191119+ @param reason: The reason given for the kick.
11201120+- @type reason: C{unicode}
11211121++ @type reason: L{str}
11221122+11231123+ @param sender: The entity sending the request.
11241124+ @type sender: L{JID<twisted.words.protocols.jabber.jid.JID>}
11251125+diff --git a/wokkel/muc.py b/wokkel/muc.py
11261126+index 330664b..4c826f2 100644
11271127+--- a/wokkel/muc.py
11281128++++ b/wokkel/muc.py
11291129+@@ -17,7 +17,6 @@ from dateutil.tz import tzutc
11301130+ from zope.interface import implementer
11311131+11321132+ from twisted.internet import defer
11331133+-from twisted.python.compat import unicode
11341134+ from twisted.python.constants import Values, ValueConstant
11351135+ from twisted.words.protocols.jabber import jid, error, xmlstream
11361136+ from twisted.words.xish import domish
11371137+@@ -192,7 +191,7 @@ class AdminItem(object):
11381138+ item.role = element.getAttribute('role')
11391139+11401140+ for child in element.elements(NS_MUC_ADMIN, 'reason'):
11411141+- item.reason = unicode(child)
11421142++ item.reason = str(child)
11431143+11441144+ return item
11451145+11461146+@@ -228,13 +227,13 @@ class DestructionRequest(generic.Request):
11471147+ Room destruction request.
11481148+11491149+ @param reason: Optional reason for the destruction of this room.
11501150+- @type reason: L{unicode}.
11511151++ @type reason: L{str}.
11521152+11531153+ @param alternate: Optional room JID of an alternate venue.
11541154+ @type alternate: L{JID<twisted.words.protocols.jabber.jid.JID>}
11551155+11561156+ @param password: Optional password for entering the alternate venue.
11571157+- @type password: L{unicode}
11581158++ @type password: L{str}
11591159+ """
11601160+11611161+ stanzaType = 'set'
11621162+@@ -395,10 +394,10 @@ class UserPresence(xmppim.AvailabilityPresence):
11631163+ Availability presence sent from MUC service to client.
11641164+11651165+ @ivar affiliation: Affiliation of the entity to the room.
11661166+- @type affiliation: L{unicode}
11671167++ @type affiliation: L{str}
11681168+11691169+ @ivar role: Role of the entity in the room.
11701170+- @type role: L{unicode}
11711171++ @type role: L{str}
11721172+11731173+ @ivar entity: The real JID of the entity this presence is from.
11741174+ @type entity: L{JID<twisted.words.protocols.jabber.jid.JID>}
11751175+@@ -408,7 +407,7 @@ class UserPresence(xmppim.AvailabilityPresence):
11761176+ @type mucStatuses: L{Statuses}
11771177+11781178+ @ivar nick: The nick name of the entity in the room.
11791179+- @type nick: L{unicode}
11801180++ @type nick: L{str}
11811181+ """
11821182+11831183+ affiliation = None
11841184+@@ -451,7 +450,7 @@ class UserPresence(xmppim.AvailabilityPresence):
11851185+ self.role = child.getAttribute('role')
11861186+11871187+ for reason in child.elements(NS_MUC_ADMIN, 'reason'):
11881188+- self.reason = unicode(reason)
11891189++ self.reason = str(reason)
11901190+11911191+ # TODO: destroy
11921192+11931193+@@ -595,14 +594,14 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
11941194+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
11951195+11961196+ @param nick: The nick name for the entitity joining the room.
11971197+- @type nick: L{unicode}
11981198++ @type nick: L{str}
11991199+12001200+ @param historyOptions: Options for conversation history sent by the
12011201+ room upon joining.
12021202+ @type historyOptions: L{HistoryOptions}
12031203+12041204+ @param password: Optional password for the room.
12051205+- @type password: L{unicode}
12061206++ @type password: L{str}
12071207+12081208+ @return: A deferred that fires when the entity is in the room or an
12091209+ error has occurred.
12101210+@@ -628,7 +627,7 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
12111211+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
12121212+12131213+ @param nick: The new nick name within the room.
12141214+- @type nick: L{unicode}
12151215++ @type nick: L{str}
12161216+ """
12171217+ occupantJID = jid.JID(tuple=(roomJID.user, roomJID.host, nick))
12181218+ presence = BasicPresence(recipient=occupantJID)
12191219+@@ -646,10 +645,10 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
12201220+12211221+ @param show: The availability of the entity. Common values are xa,
12221222+ available, etc
12231223+- @type show: L{unicode}
12241224++ @type show: L{str}
12251225+12261226+ @param status: The current status of the entity.
12271227+- @type status: L{unicode}
12281228++ @type status: L{str}
12291229+ """
12301230+ occupantJID = self._roomOccupantMap[roomJID]
12311231+ presence = BasicPresence(recipient=occupantJID, show=show,
12321232+@@ -704,7 +703,7 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
12331233+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
12341234+12351235+ @param subject: The subject you want to set.
12361236+- @type subject: L{unicode}
12371237++ @type subject: L{str}
12381238+ """
12391239+ message = GroupChat(roomJID.userhostJID(), subject=subject)
12401240+ self.send(message.toElement())
12411241+@@ -723,7 +722,7 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
12421242+ @type invitee: L{JID<twisted.words.protocols.jabber.jid.JID>}
12431243+12441244+ @param reason: The reason for the invite.
12451245+- @type reason: L{unicode}
12461246++ @type reason: L{str}
12471247+ """
12481248+ message = InviteMessage(recipient=roomJID, invitee=invitee,
12491249+ reason=reason)
12501250+@@ -970,7 +969,7 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
12511251+ L{JID<twisted.words.protocols.jabber.jid.JID>}
12521252+12531253+ @param affiliation: The affilation to the entities will acquire.
12541254+- @type affiliation: L{unicode}
12551255++ @type affiliation: L{str}
12561256+12571257+ @param sender: The entity sending the request.
12581258+ @type sender: L{JID<twisted.words.protocols.jabber.jid.JID>}
12591259+@@ -992,10 +991,10 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
12601260+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
12611261+12621262+ @param nick: The nick name for the user in this room.
12631263+- @type nick: L{unicode}
12641264++ @type nick: L{str}
12651265+12661266+ @param reason: The reason for granting voice to the entity.
12671267+- @type reason: L{unicode}
12681268++ @type reason: L{str}
12691269+12701270+ @param sender: The entity sending the request.
12711271+ @type sender: L{JID<twisted.words.protocols.jabber.jid.JID>}
12721272+@@ -1015,10 +1014,10 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
12731273+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
12741274+12751275+ @param nick: The nick name for the user in this room.
12761276+- @type nick: L{unicode}
12771277++ @type nick: L{str}
12781278+12791279+ @param reason: The reason for revoking voice from the entity.
12801280+- @type reason: L{unicode}
12811281++ @type reason: L{str}
12821282+12831283+ @param sender: The entity sending the request.
12841284+ @type sender: L{JID<twisted.words.protocols.jabber.jid.JID>}
12851285+@@ -1035,10 +1034,10 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
12861286+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
12871287+12881288+ @param nick: The nick name for the user in this room.
12891289+- @type nick: L{unicode}
12901290++ @type nick: L{str}
12911291+12921292+ @param reason: The reason for granting moderation to the entity.
12931293+- @type reason: L{unicode}
12941294++ @type reason: L{str}
12951295+12961296+ @param sender: The entity sending the request.
12971297+ @type sender: L{JID<twisted.words.protocols.jabber.jid.JID>}
12981298+@@ -1058,7 +1057,7 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
12991299+ @type entity: L{JID<twisted.words.protocols.jabber.jid.JID>}
13001300+13011301+ @param reason: The reason for banning the entity.
13021302+- @type reason: L{unicode}
13031303++ @type reason: L{str}
13041304+13051305+ @param sender: The entity sending the request.
13061306+ @type sender: L{JID<twisted.words.protocols.jabber.jid.JID>}
13071307+@@ -1075,10 +1074,10 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
13081308+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
13091309+13101310+ @param nick: The occupant to be banned.
13111311+- @type nick: L{unicode}
13121312++ @type nick: L{str}
13131313+13141314+ @param reason: The reason given for the kick.
13151315+- @type reason: L{unicode}
13161316++ @type reason: L{str}
13171317+13181318+ @param sender: The entity sending the request.
13191319+ @type sender: L{JID<twisted.words.protocols.jabber.jid.JID>}
13201320+@@ -1095,7 +1094,7 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
13211321+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
13221322+13231323+ @param reason: The reason for the destruction of the room.
13241324+- @type reason: L{unicode}
13251325++ @type reason: L{str}
13261326+13271327+ @param alternate: The JID of the room suggested as an alternate venue.
13281328+ @type alternate: L{JID<twisted.words.protocols.jabber.jid.JID>}
13291329+@@ -1135,7 +1134,7 @@ class Room(object):
13301330+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
13311331+13321332+ @ivar nick: The nick name for the client in this room.
13331333+- @type nick: L{unicode}
13341334++ @type nick: L{str}
13351335+13361336+ @ivar occupantJID: The JID of the occupant in the room. Generated from
13371337+ roomJID and nick.
13381338+@@ -1190,7 +1189,7 @@ class Room(object):
13391339+ Get a user from the room's roster.
13401340+13411341+ @param nick: The nick for the user in the MUC room.
13421342+- @type nick: L{unicode}
13431343++ @type nick: L{str}
13441344+ """
13451345+ return self.roster.get(nick)
13461346+13471347+@@ -1444,14 +1443,14 @@ class MUCClient(MUCClientProtocol):
13481348+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
13491349+13501350+ @param nick: The nick name for the entitity joining the room.
13511351+- @type nick: L{unicode}
13521352++ @type nick: L{str}
13531353+13541354+ @param historyOptions: Options for conversation history sent by the
13551355+ room upon joining.
13561356+ @type historyOptions: L{HistoryOptions}
13571357+13581358+ @param password: Optional password for the room.
13591359+- @type password: L{unicode}
13601360++ @type password: L{str}
13611361+13621362+ @return: A deferred that fires with the room when the entity is in the
13631363+ room, or with a failure if an error has occurred.
13641364+@@ -1488,7 +1487,7 @@ class MUCClient(MUCClientProtocol):
13651365+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
13661366+13671367+ @param nick: The new nick name within the room.
13681368+- @type nick: L{unicode}
13691369++ @type nick: L{str}
13701370+ """
13711371+ def cb(presence):
13721372+ # Presence confirmation, change the nickname.
13731373+@@ -1530,10 +1529,10 @@ class MUCClient(MUCClientProtocol):
13741374+13751375+ @param show: The availability of the entity. Common values are xa,
13761376+ available, etc
13771377+- @type show: L{unicode}
13781378++ @type show: L{str}
13791379+13801380+ @param status: The current status of the entity.
13811381+- @type status: L{unicode}
13821382++ @type status: L{str}
13831383+ """
13841384+ room = self._getRoom(roomJID)
13851385+ d = MUCClientProtocol.status(self, roomJID, show, status)
13861386+@@ -1549,7 +1548,7 @@ class MUCClient(MUCClientProtocol):
13871387+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
13881388+13891389+ @param reason: The reason for the destruction of the room.
13901390+- @type reason: L{unicode}
13911391++ @type reason: L{str}
13921392+13931393+ @param alternate: The JID of the room suggested as an alternate venue.
13941394+ @type alternate: L{JID<twisted.words.protocols.jabber.jid.JID>}
13951395+diff --git a/wokkel/pubsub.py b/wokkel/pubsub.py
13961396+index 689a6e2..2eb1b44 100644
13971397+--- a/wokkel/pubsub.py
13981398++++ b/wokkel/pubsub.py
13991399+@@ -16,7 +16,6 @@ from zope.interface import implementer
14001400+14011401+ from twisted.internet import defer
14021402+ from twisted.python import log
14031403+-from twisted.python.compat import StringType, iteritems, unicode
14041404+ from twisted.words.protocols.jabber import jid, error
14051405+ from twisted.words.xish import domish
14061406+14071407+@@ -107,20 +106,20 @@ class Subscription(object):
14081408+14091409+ @ivar nodeIdentifier: The identifier of the node subscribed to. The root
14101410+ node is denoted by L{None}.
14111411+- @type nodeIdentifier: L{unicode}
14121412++ @type nodeIdentifier: L{str}
14131413+14141414+ @ivar subscriber: The subscribing entity.
14151415+ @type subscriber: L{jid.JID}
14161416+14171417+ @ivar state: The subscription state. One of C{'subscribed'}, C{'pending'},
14181418+ C{'unconfigured'}.
14191419+- @type state: L{unicode}
14201420++ @type state: L{str}
14211421+14221422+ @ivar options: Optional list of subscription options.
14231423+ @type options: L{dict}
14241424+14251425+ @ivar subscriptionIdentifier: Optional subscription identifier.
14261426+- @type subscriptionIdentifier: L{unicode}
14271427++ @type subscriptionIdentifier: L{str}
14281428+ """
14291429+14301430+ def __init__(self, nodeIdentifier, subscriber, state, options=None,
14311431+@@ -150,7 +149,7 @@ class Subscription(object):
14321432+ element = domish.Element((defaultUri, 'subscription'))
14331433+ if self.nodeIdentifier:
14341434+ element['node'] = self.nodeIdentifier
14351435+- element['jid'] = unicode(self.subscriber)
14361436++ element['jid'] = str(self.subscriber)
14371437+ element['subscription'] = self.state
14381438+ if self.subscriptionIdentifier:
14391439+ element['subid'] = self.subscriptionIdentifier
14401440+@@ -171,17 +170,17 @@ class Item(domish.Element):
14411441+ def __init__(self, id=None, payload=None):
14421442+ """
14431443+ @param id: optional item identifier
14441444+- @type id: L{unicode}
14451445++ @type id: L{str}
14461446+ @param payload: optional item payload. Either as a domish element, or
14471447+ as serialized XML.
14481448+- @type payload: object providing L{domish.IElement} or L{unicode}.
14491449++ @type payload: object providing L{domish.IElement} or L{str}.
14501450+ """
14511451+14521452+ domish.Element.__init__(self, (None, 'item'))
14531453+ if id is not None:
14541454+ self['id'] = id
14551455+ if payload is not None:
14561456+- if isinstance(payload, StringType):
14571457++ if isinstance(payload, str):
14581458+ self.addRawXml(payload)
14591459+ else:
14601460+ self.addChild(payload)
14611461+@@ -213,7 +212,7 @@ class PubSubRequest(generic.Stanza):
14621462+ @type maxItems: L{int}.
14631463+14641464+ @ivar nodeIdentifier: Identifier of the node the request is about.
14651465+- @type nodeIdentifier: L{unicode}
14661466++ @type nodeIdentifier: L{str}
14671467+14681468+ @ivar nodeType: The type of node that should be created, or for which the
14691469+ configuration is retrieved. C{'leaf'} or C{'collection'}.
14701470+@@ -227,7 +226,7 @@ class PubSubRequest(generic.Stanza):
14711471+ @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
14721472+14731473+ @ivar subscriptionIdentifier: Identifier for a specific subscription.
14741474+- @type subscriptionIdentifier: L{unicode}
14751475++ @type subscriptionIdentifier: L{str}
14761476+14771477+ @ivar subscriptions: Subscriptions to be modified, as a set of
14781478+ L{Subscription}.
14791479+@@ -235,7 +234,7 @@ class PubSubRequest(generic.Stanza):
14801480+14811481+ @ivar affiliations: Affiliations to be modified, as a dictionary of entity
14821482+ (L{JID<twisted.words.protocols.jabber.jid.JID>} to affiliation
14831483+- (L{unicode}).
14841484++ (L{str}).
14851485+ @type affiliations: L{dict}
14861486+ """
14871487+14881488+@@ -277,7 +276,7 @@ class PubSubRequest(generic.Stanza):
14891489+ }
14901490+14911491+ # Map request verb to request iq type and subelement name
14921492+- _verbRequestMap = dict(((v, k) for k, v in iteritems(_requestVerbMap)))
14931493++ _verbRequestMap = dict(((v, k) for k, v in _requestVerbMap.items()))
14941494+14951495+ # Map request verb to parameter handler names
14961496+ _parameters = {
14971497+@@ -487,7 +486,7 @@ class PubSubRequest(generic.Stanza):
14981498+ Render maximum items into an items request.
14991499+ """
15001500+ if self.maxItems:
15011501+- verbElement['max_items'] = unicode(self.maxItems)
15021502++ verbElement['max_items'] = str(self.maxItems)
15031503+15041504+15051505+ def _parse_subidOrNone(self, verbElement):
15061506+@@ -648,7 +647,7 @@ class PubSubEvent(object):
15071507+ @param recipient: The entity to which the notification was sent.
15081508+ @type recipient: L{wokkel.pubsub.ItemsEvent}
15091509+ @param nodeIdentifier: Identifier of the node the event pertains to.
15101510+- @type nodeIdentifier: L{unicode}
15111511++ @type nodeIdentifier: L{str}
15121512+ @param headers: SHIM headers, see L{wokkel.shim.extractHeaders}.
15131513+ @type headers: L{dict}
15141514+ """
15151515+@@ -772,7 +771,7 @@ class PubSubClient(XMPPHandler):
15161516+ @param service: The publish subscribe service to create the node at.
15171517+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
15181518+ @param nodeIdentifier: Optional suggestion for the id of the node.
15191519+- @type nodeIdentifier: L{unicode}
15201520++ @type nodeIdentifier: L{str}
15211521+ @param options: Optional node configuration options.
15221522+ @type options: L{dict}
15231523+ """
15241524+@@ -807,7 +806,7 @@ class PubSubClient(XMPPHandler):
15251525+ @param service: The publish subscribe service to delete the node from.
15261526+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
15271527+ @param nodeIdentifier: The identifier of the node.
15281528+- @type nodeIdentifier: L{unicode}
15291529++ @type nodeIdentifier: L{str}
15301530+ """
15311531+ request = PubSubRequest('delete')
15321532+ request.recipient = service
15331533+@@ -825,7 +824,7 @@ class PubSubClient(XMPPHandler):
15341534+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
15351535+15361536+ @param nodeIdentifier: The identifier of the node.
15371537+- @type nodeIdentifier: L{unicode}
15381538++ @type nodeIdentifier: L{str}
15391539+15401540+ @param subscriber: The entity to subscribe to the node. This entity
15411541+ will get notifications of new published items.
15421542+@@ -877,13 +876,13 @@ class PubSubClient(XMPPHandler):
15431543+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
15441544+15451545+ @param nodeIdentifier: The identifier of the node.
15461546+- @type nodeIdentifier: L{unicode}
15471547++ @type nodeIdentifier: L{str}
15481548+15491549+ @param subscriber: The entity to unsubscribe from the node.
15501550+ @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
15511551+15521552+ @param subscriptionIdentifier: Optional subscription identifier.
15531553+- @type subscriptionIdentifier: L{unicode}
15541554++ @type subscriptionIdentifier: L{str}
15551555+ """
15561556+ request = PubSubRequest('unsubscribe')
15571557+ request.recipient = service
15581558+@@ -901,7 +900,7 @@ class PubSubClient(XMPPHandler):
15591559+ @param service: The publish subscribe service that keeps the node.
15601560+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
15611561+ @param nodeIdentifier: The identifier of the node.
15621562+- @type nodeIdentifier: L{unicode}
15631563++ @type nodeIdentifier: L{str}
15641564+ @param items: Optional list of L{Item}s to publish.
15651565+ @type items: L{list}
15661566+ """
15671567+@@ -922,7 +921,7 @@ class PubSubClient(XMPPHandler):
15681568+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
15691569+15701570+ @param nodeIdentifier: The identifier of the node.
15711571+- @type nodeIdentifier: L{unicode}
15721572++ @type nodeIdentifier: L{str}
15731573+15741574+ @param maxItems: Optional limit on the number of retrieved items.
15751575+ @type maxItems: L{int}
15761576+@@ -930,10 +929,10 @@ class PubSubClient(XMPPHandler):
15771577+ @param subscriptionIdentifier: Optional subscription identifier. In
15781578+ case the node has been subscribed to multiple times, this narrows
15791579+ the results to the specific subscription.
15801580+- @type subscriptionIdentifier: L{unicode}
15811581++ @type subscriptionIdentifier: L{str}
15821582+15831583+ @param itemIdentifiers: Identifiers of the items to be retrieved.
15841584+- @type itemIdentifiers: L{set} of L{unicode}
15851585++ @type itemIdentifiers: L{set} of L{str}
15861586+ """
15871587+ request = PubSubRequest('items')
15881588+ request.recipient = service
15891589+@@ -965,13 +964,13 @@ class PubSubClient(XMPPHandler):
15901590+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
15911591+15921592+ @param nodeIdentifier: The identifier of the node.
15931593+- @type nodeIdentifier: L{unicode}
15941594++ @type nodeIdentifier: L{str}
15951595+15961596+ @param subscriber: The entity subscribed to the node.
15971597+ @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
15981598+15991599+ @param subscriptionIdentifier: Optional subscription identifier.
16001600+- @type subscriptionIdentifier: L{unicode}
16011601++ @type subscriptionIdentifier: L{str}
16021602+16031603+ @rtype: L{data_form.Form}
16041604+ """
16051605+@@ -1002,7 +1001,7 @@ class PubSubClient(XMPPHandler):
16061606+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
16071607+16081608+ @param nodeIdentifier: The identifier of the node.
16091609+- @type nodeIdentifier: L{unicode}
16101610++ @type nodeIdentifier: L{str}
16111611+16121612+ @param subscriber: The entity subscribed to the node.
16131613+ @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
16141614+@@ -1011,7 +1010,7 @@ class PubSubClient(XMPPHandler):
16151615+ @type options: L{dict}.
16161616+16171617+ @param subscriptionIdentifier: Optional subscription identifier.
16181618+- @type subscriptionIdentifier: L{unicode}
16191619++ @type subscriptionIdentifier: L{str}
16201620+ """
16211621+ request = PubSubRequest('optionsSet')
16221622+ request.recipient = service
16231623+@@ -1356,7 +1355,7 @@ class PubSubService(XMPPHandler, IQHandlerMixin):
16241624+ if request.nodeIdentifier:
16251625+ affiliations['node'] = request.nodeIdentifier
16261626+16271627+- for entity, affiliation in iteritems(result):
16281628++ for entity, affiliation in result.items():
16291629+ item = affiliations.addElement('affiliation')
16301630+ item['jid'] = entity.full()
16311631+ item['affiliation'] = affiliation
16321632+diff --git a/wokkel/server.py b/wokkel/server.py
16331633+index 54517a2..fbd8452 100644
16341634+--- a/wokkel/server.py
16351635++++ b/wokkel/server.py
16361636+@@ -22,7 +22,6 @@ from zope.interface import implementer
16371637+ from twisted.internet import defer, reactor
16381638+ from twisted.names.srvconnect import SRVConnector
16391639+ from twisted.python import log, randbytes
16401640+-from twisted.python.compat import iteritems, unicode
16411641+ from twisted.words.protocols.jabber import error, ijabber, jid, xmlstream
16421642+ from twisted.words.xish import domish
16431643+16441644+@@ -40,15 +39,15 @@ def generateKey(secret, receivingServer, originatingServer, streamID):
16451645+16461646+ @param secret: the shared secret known to the Originating Server and
16471647+ Authoritive Server.
16481648+- @type secret: L{unicode}
16491649++ @type secret: L{str}
16501650+ @param receivingServer: the Receiving Server host name.
16511651+- @type receivingServer: L{unicode}
16521652++ @type receivingServer: L{str}
16531653+ @param originatingServer: the Originating Server host name.
16541654+- @type originatingServer: L{unicode}
16551655++ @type originatingServer: L{str}
16561656+ @param streamID: the Stream ID as generated by the Receiving Server.
16571657+- @type streamID: L{unicode}
16581658++ @type streamID: L{str}
16591659+ @return: hexadecimal digest of the generated key.
16601660+- @type: C{str}
16611661++ @type: L{str}
16621662+ """
16631663+16641664+ hashObject = sha256()
16651665+@@ -340,7 +339,7 @@ class XMPPServerListenAuthenticator(xmlstream.ListenAuthenticator):
16661666+ try:
16671667+ if xmlstream.NS_STREAMS != rootElement.uri or \
16681668+ self.namespace != self.xmlstream.namespace or \
16691669+- ('db', NS_DIALBACK) not in iteritems(rootElement.localPrefixes):
16701670++ ('db', NS_DIALBACK) not in rootElement.localPrefixes.items():
16711671+ raise error.StreamError('invalid-namespace')
16721672+16731673+ if targetDomain and targetDomain not in self.service.domains:
16741674+@@ -379,7 +378,7 @@ class XMPPServerListenAuthenticator(xmlstream.ListenAuthenticator):
16751675+ raise error.StreamError('invalid-from')
16761676+16771677+ streamID = verify.getAttribute('id', '')
16781678+- key = unicode(verify)
16791679++ key = str(verify)
16801680+16811681+ calculatedKey = generateKey(self.service.secret, receivingServer,
16821682+ originatingServer, streamID)
16831683+@@ -415,7 +414,7 @@ class XMPPServerListenAuthenticator(xmlstream.ListenAuthenticator):
16841684+16851685+ receivingServer = result['to']
16861686+ originatingServer = result['from']
16871687+- key = unicode(result)
16881688++ key = str(result)
16891689+16901690+ d = self.service.validateConnection(receivingServer, originatingServer,
16911691+ self.xmlstream.sid, key)
16921692+diff --git a/wokkel/shim.py b/wokkel/shim.py
16931693+index 3b12349..85a0848 100644
16941694+--- a/wokkel/shim.py
16951695++++ b/wokkel/shim.py
16961696+@@ -12,7 +12,6 @@ U{XEP-0131<http://xmpp.org/extensions/xep-0131.html>}.
16971697+16981698+ from __future__ import division, absolute_import
16991699+17001700+-from twisted.python.compat import unicode
17011701+ from twisted.words.xish import domish
17021702+17031703+ NS_SHIM = "http://jabber.org/protocol/shim"
17041704+@@ -30,7 +29,7 @@ def extractHeaders(stanza):
17051705+ @param stanza: The stanza to extract headers from.
17061706+ @type stanza: L{Element<twisted.words.xish.domish.Element>}
17071707+ @return: Headers as a mapping from header name to a list of values.
17081708+- @rtype: C{dict}
17091709++ @rtype: L{dict}
17101710+ """
17111711+ headers = {}
17121712+17131713+@@ -38,6 +37,6 @@ def extractHeaders(stanza):
17141714+ 'headers', NS_SHIM):
17151715+ for header in domish.generateElementsQNamed(element.children,
17161716+ 'header', NS_SHIM):
17171717+- headers.setdefault(header['name'], []).append(unicode(header))
17181718++ headers.setdefault(header['name'], []).append(str(header))
17191719+17201720+ return headers
17211721+diff --git a/wokkel/subprotocols.py b/wokkel/subprotocols.py
17221722+index f0a6090..b4cde14 100644
17231723+--- a/wokkel/subprotocols.py
17241724++++ b/wokkel/subprotocols.py
17251725+@@ -14,7 +14,6 @@ from zope.interface import implementer
17261726+ from twisted.internet import defer
17271727+ from twisted.internet.error import ConnectionDone
17281728+ from twisted.python import failure, log
17291729+-from twisted.python.compat import iteritems, itervalues
17301730+ from twisted.python.deprecate import deprecatedModuleAttribute
17311731+ from twisted.words.protocols.jabber import error, ijabber, xmlstream
17321732+ from twisted.words.protocols.jabber.xmlstream import toResponse
17331733+@@ -130,15 +129,15 @@ class StreamManager(XMPPHandlerCollection):
17341734+ @ivar xmlstream: currently managed XML stream
17351735+ @type xmlstream: L{XmlStream}
17361736+ @ivar logTraffic: if true, log all traffic.
17371737+- @type logTraffic: C{bool}
17381738++ @type logTraffic: L{bool}
17391739+ @ivar _initialized: Whether the stream represented by L{xmlstream} has
17401740+ been initialized. This is used when caching outgoing
17411741+ stanzas.
17421742+- @type _initialized: C{bool}
17431743++ @type _initialized: L{bool}
17441744+ @ivar _packetQueue: internal buffer of unsent data. See L{send} for details.
17451745+ @type _packetQueue: L{list}
17461746+ @ivar timeout: Default IQ request timeout in seconds.
17471747+- @type timeout: C{int}
17481748++ @type timeout: L{int}
17491749+ @ivar _reactor: A provider of L{IReactorTime} to track timeouts.
17501750+ """
17511751+ timeout = None
17521752+@@ -277,7 +276,7 @@ class StreamManager(XMPPHandlerCollection):
17531753+ # deferreds will never be fired.
17541754+ iqDeferreds = self._iqDeferreds
17551755+ self._iqDeferreds = {}
17561756+- for d in itervalues(iqDeferreds):
17571757++ for d in iqDeferreds.values():
17581758+ d.errback(reason)
17591759+17601760+17611761+@@ -420,7 +419,7 @@ class IQHandlerMixin(object):
17621762+17631763+ @cvar iqHandlers: Mapping from XPath queries (as a string) to the method
17641764+ name that will handle requests that match the query.
17651765+- @type iqHandlers: C{dict}
17661766++ @type iqHandlers: L{dict}
17671767+ """
17681768+17691769+ iqHandlers = None
17701770+@@ -455,7 +454,7 @@ class IQHandlerMixin(object):
17711771+ return error.StanzaError('internal-server-error').toResponse(iq)
17721772+17731773+ handler = None
17741774+- for queryString, method in iteritems(self.iqHandlers):
17751775++ for queryString, method in self.iqHandlers.items():
17761776+ if xpath.internQuery(queryString).matches(iq):
17771777+ handler = getattr(self, method)
17781778+17791779+diff --git a/wokkel/test/helpers.py b/wokkel/test/helpers.py
17801780+index 102b3dc..c76a4a0 100644
17811781+--- a/wokkel/test/helpers.py
17821782++++ b/wokkel/test/helpers.py
17831783+@@ -8,7 +8,6 @@ Unit test helpers.
17841784+ from __future__ import division, absolute_import
17851785+17861786+ from twisted.internet import defer
17871787+-from twisted.python.compat import iteritems
17881788+ from twisted.words.xish import xpath
17891789+ from twisted.words.xish.utility import EventDispatcher
17901790+17911791+@@ -79,14 +78,14 @@ class TestableRequestHandlerMixin(object):
17921792+ Find a handler and call it directly.
17931793+17941794+ @param xml: XML stanza that may yield a handler being called.
17951795+- @type xml: C{str}.
17961796++ @type xml: L{str}.
17971797+ @return: Deferred that fires with the result of a handler for this
17981798+ stanza. If no handler was found, the deferred has its errback
17991799+ called with a C{NotImplementedError} exception.
18001800+ """
18011801+ handler = None
18021802+ iq = parseXml(xml)
18031803+- for queryString, method in iteritems(self.service.iqHandlers):
18041804++ for queryString, method in self.service.iqHandlers.items():
18051805+ if xpath.internQuery(queryString).matches(iq):
18061806+ handler = getattr(self.service, method)
18071807+18081808+diff --git a/wokkel/test/test_client.py b/wokkel/test/test_client.py
18091809+index ef367f7..ef9adfd 100644
18101810+--- a/wokkel/test/test_client.py
18111811++++ b/wokkel/test/test_client.py
18121812+@@ -8,6 +8,7 @@ Tests for L{wokkel.client}.
18131813+ from __future__ import division, absolute_import
18141814+18151815+ from twisted.internet import defer
18161816++from twisted.python.compat import nativeString
18171817+ from twisted.trial import unittest
18181818+ from twisted.words.protocols.jabber import xmlstream
18191819+ from twisted.words.protocols.jabber.client import XMPPAuthenticator
18201820+@@ -152,7 +153,7 @@ class ClientCreatorTest(unittest.TestCase):
18211821+18221822+ def cb(connector):
18231823+ self.assertEqual('xmpp-client', connector.service)
18241824+- self.assertEqual('example.org', connector.domain)
18251825++ self.assertEqual('example.org', nativeString(connector.domain))
18261826+ self.assertEqual(factory, connector.factory)
18271827+18281828+ def connect(connector):
18291829+diff --git a/wokkel/test/test_data_form.py b/wokkel/test/test_data_form.py
18301830+index 60e36f4..246f1c5 100644
18311831+--- a/wokkel/test/test_data_form.py
18321832++++ b/wokkel/test/test_data_form.py
18331833+@@ -10,7 +10,6 @@ from __future__ import division, absolute_import
18341834+ from zope.interface import verify
18351835+ from zope.interface.common.mapping import IIterableMapping
18361836+18371837+-from twisted.python.compat import unicode, _PY3
18381838+ from twisted.trial import unittest
18391839+ from twisted.words.xish import domish
18401840+ from twisted.words.protocols.jabber import jid
18411841+@@ -34,7 +33,7 @@ class OptionTest(unittest.TestCase):
18421842+ self.assertEqual('option', element.name)
18431843+ self.assertEqual(NS_X_DATA, element.uri)
18441844+ self.assertEqual(NS_X_DATA, element.value.uri)
18451845+- self.assertEqual('value', unicode(element.value))
18461846++ self.assertEqual('value', str(element.value))
18471847+ self.assertFalse(element.hasAttribute('label'))
18481848+18491849+18501850+@@ -48,7 +47,7 @@ class OptionTest(unittest.TestCase):
18511851+ self.assertEqual('option', element.name)
18521852+ self.assertEqual(NS_X_DATA, element.uri)
18531853+ self.assertEqual(NS_X_DATA, element.value.uri)
18541854+- self.assertEqual('value', unicode(element.value))
18551855++ self.assertEqual('value', str(element.value))
18561856+ self.assertEqual('label', element['label'])
18571857+18581858+18591859+@@ -225,7 +224,7 @@ class FieldTest(unittest.TestCase):
18601860+ child = element.children[0]
18611861+ self.assertEqual('desc', child.name)
18621862+ self.assertEqual(NS_X_DATA, child.uri)
18631863+- self.assertEqual(u'My desc', unicode(child))
18641864++ self.assertEqual(u'My desc', str(child))
18651865+18661866+18671867+ def test_toElementRequired(self):
18681868+@@ -248,7 +247,7 @@ class FieldTest(unittest.TestCase):
18691869+ field = data_form.Field(fieldType='jid-single', var='test',
18701870+ value=jid.JID(u'test@example.org'))
18711871+ element = field.toElement()
18721872+- self.assertEqual(u'test@example.org', unicode(element.value))
18731873++ self.assertEqual(u'test@example.org', str(element.value))
18741874+18751875+18761876+ def test_toElementJIDTextSingle(self):
18771877+@@ -258,7 +257,7 @@ class FieldTest(unittest.TestCase):
18781878+ field = data_form.Field(fieldType='text-single', var='test',
18791879+ value=jid.JID(u'test@example.org'))
18801880+ element = field.toElement()
18811881+- self.assertEqual(u'test@example.org', unicode(element.value))
18821882++ self.assertEqual(u'test@example.org', str(element.value))
18831883+18841884+18851885+ def test_toElementBoolean(self):
18861886+@@ -268,7 +267,7 @@ class FieldTest(unittest.TestCase):
18871887+ field = data_form.Field(fieldType='boolean', var='test',
18881888+ value=True)
18891889+ element = field.toElement()
18901890+- self.assertEqual(u'true', unicode(element.value))
18911891++ self.assertEqual(u'true', str(element.value))
18921892+18931893+18941894+ def test_toElementBooleanTextSingle(self):
18951895+@@ -277,7 +276,7 @@ class FieldTest(unittest.TestCase):
18961896+ """
18971897+ field = data_form.Field(var='test', value=True)
18981898+ element = field.toElement()
18991899+- self.assertEqual(u'true', unicode(element.value))
19001900++ self.assertEqual(u'true', str(element.value))
19011901+19021902+19031903+ def test_toElementNoType(self):
19041904+@@ -396,7 +395,7 @@ class FieldTest(unittest.TestCase):
19051905+19061906+ def test_fromElementValueTextSingle(self):
19071907+ """
19081908+- Parsed text-single field values should be of type C{unicode}.
19091909++ Parsed text-single field values should be of type L{str}.
19101910+ """
19111911+ element = domish.Element((NS_X_DATA, 'field'))
19121912+ element['type'] = 'text-single'
19131913+@@ -407,7 +406,7 @@ class FieldTest(unittest.TestCase):
19141914+19151915+ def test_fromElementValueJID(self):
19161916+ """
19171917+- Parsed jid-single field values should be of type C{unicode}.
19181918++ Parsed jid-single field values should be of type L{str}.
19191919+ """
19201920+ element = domish.Element((NS_X_DATA, 'field'))
19211921+ element['type'] = 'jid-single'
19221922+@@ -418,7 +417,7 @@ class FieldTest(unittest.TestCase):
19231923+19241924+ def test_fromElementValueJIDMalformed(self):
19251925+ """
19261926+- Parsed jid-single field values should be of type C{unicode}.
19271927++ Parsed jid-single field values should be of type L{str}.
19281928+19291929+ No validation should be done at this point, so invalid JIDs should
19301930+ also be passed as-is.
19311931+@@ -432,7 +431,7 @@ class FieldTest(unittest.TestCase):
19321932+19331933+ def test_fromElementValueBoolean(self):
19341934+ """
19351935+- Parsed boolean field values should be of type C{unicode}.
19361936++ Parsed boolean field values should be of type L{str}.
19371937+ """
19381938+ element = domish.Element((NS_X_DATA, 'field'))
19391939+ element['type'] = 'boolean'
19401940+@@ -561,7 +560,7 @@ class FormTest(unittest.TestCase):
19411941+ title = elements[0]
19421942+ self.assertEqual('title', title.name)
19431943+ self.assertEqual(NS_X_DATA, title.uri)
19441944+- self.assertEqual('Bot configuration', unicode(title))
19451945++ self.assertEqual('Bot configuration', str(title))
19461946+19471947+19481948+ def test_toElementInstructions(self):
19491949+@@ -576,7 +575,7 @@ class FormTest(unittest.TestCase):
19501950+ instructions = elements[0]
19511951+ self.assertEqual('instructions', instructions.name)
19521952+ self.assertEqual(NS_X_DATA, instructions.uri)
19531953+- self.assertEqual('Fill out this form!', unicode(instructions))
19541954++ self.assertEqual('Fill out this form!', str(instructions))
19551955+19561956+19571957+ def test_toElementInstructionsMultiple(self):
19581958+@@ -593,10 +592,10 @@ class FormTest(unittest.TestCase):
19591959+ instructions2 = elements[1]
19601960+ self.assertEqual('instructions', instructions1.name)
19611961+ self.assertEqual(NS_X_DATA, instructions1.uri)
19621962+- self.assertEqual('Fill out this form!', unicode(instructions1))
19631963++ self.assertEqual('Fill out this form!', str(instructions1))
19641964+ self.assertEqual('instructions', instructions2.name)
19651965+ self.assertEqual(NS_X_DATA, instructions2.uri)
19661966+- self.assertEqual('no really', unicode(instructions2))
19671967++ self.assertEqual('no really', str(instructions2))
19681968+19691969+19701970+ def test_toElementFormType(self):
19711971+@@ -613,7 +612,7 @@ class FormTest(unittest.TestCase):
19721972+ self.assertEqual(NS_X_DATA, formTypeField.uri)
19731973+ self.assertEqual('FORM_TYPE', formTypeField['var'])
19741974+ self.assertEqual('hidden', formTypeField['type'])
19751975+- self.assertEqual('jabber:bot', unicode(formTypeField.value))
19761976++ self.assertEqual('jabber:bot', str(formTypeField.value))
19771977+19781978+19791979+ def test_toElementFields(self):
19801980+@@ -1091,7 +1090,7 @@ class FormTest(unittest.TestCase):
19811981+ self.assertNotIn('features', form)
19821982+19831983+19841984+- def test_iterkeys(self):
19851985++ def test_keys(self):
19861986+ """
19871987+ Iterating over the keys of a form yields all field names.
19881988+ """
19891989+@@ -1101,10 +1100,10 @@ class FormTest(unittest.TestCase):
19901990+ values=['news', 'search'])]
19911991+ form = data_form.Form('submit', fields=fields)
19921992+ self.assertEqual(set(['botname', 'public', 'features']),
19931993+- set(form.iterkeys()))
19941994++ set(form.keys()))
19951995+19961996+19971997+- def test_itervalues(self):
19981998++ def test_values(self):
19991999+ """
20002000+ Iterating over the values of a form yields all field values.
20012001+ """
20022002+@@ -1112,63 +1111,19 @@ class FormTest(unittest.TestCase):
20032003+ data_form.Field('boolean', var='public', value=True)]
20042004+ form = data_form.Form('submit', fields=fields)
20052005+ self.assertEqual(set(['The Jabber Bot', True]),
20062006+- set(form.itervalues()))
20072007+-
20082008+-
20092009+- def test_iteritems(self):
20102010+- """
20112011+- Iterating over the values of a form yields all item tuples.
20122012+- """
20132013+- fields = [data_form.Field(var='botname', value='The Jabber Bot'),
20142014+- data_form.Field('boolean', var='public', value=True)]
20152015+- form = data_form.Form('submit', fields=fields)
20162016+- self.assertEqual(set([('botname', 'The Jabber Bot'),
20172017+- ('public', True)]),
20182018+- set(form.iteritems()))
20192019+-
20202020+-
20212021+- def test_keys(self):
20222022+- """
20232023+- Getting the keys of a form yields a list of field names.
20242024+- """
20252025+- fields = [data_form.Field(var='botname', value='The Jabber Bot'),
20262026+- data_form.Field('boolean', var='public', value=True),
20272027+- data_form.Field('list-multi', var='features',
20282028+- values=['news', 'search'])]
20292029+- form = data_form.Form('submit', fields=fields)
20302030+- keys = form.keys()
20312031+- if not _PY3:
20322032+- self.assertIsInstance(keys, list)
20332033+- self.assertEqual(set(['botname', 'public', 'features']),
20342034+- set(keys))
20352035+-
20362036+-
20372037+- def test_values(self):
20382038+- """
20392039+- Getting the values of a form yields a list of field values.
20402040+- """
20412041+- fields = [data_form.Field(var='botname', value='The Jabber Bot'),
20422042+- data_form.Field('boolean', var='public', value=True)]
20432043+- form = data_form.Form('submit', fields=fields)
20442044+- values = form.values()
20452045+- if not _PY3:
20462046+- self.assertIsInstance(values, list)
20472047+- self.assertEqual(set(['The Jabber Bot', True]), set(values))
20482048++ set(form.values()))
20492049+20502050+20512051+ def test_items(self):
20522052+ """
20532053+- Iterating over the values of a form yields a list of all item tuples.
20542054++ Iterating over the values of a form yields all item tuples.
20552055+ """
20562056+ fields = [data_form.Field(var='botname', value='The Jabber Bot'),
20572057+ data_form.Field('boolean', var='public', value=True)]
20582058+ form = data_form.Form('submit', fields=fields)
20592059+- items = form.items()
20602060+- if not _PY3:
20612061+- self.assertIsInstance(items, list)
20622062+ self.assertEqual(set([('botname', 'The Jabber Bot'),
20632063+ ('public', True)]),
20642064+- set(items))
20652065++ set(form.items()))
20662066+20672067+20682068+ def test_getValues(self):
20692069+diff --git a/wokkel/test/test_generic.py b/wokkel/test/test_generic.py
20702070+index 94c39e5..4e4ab45 100644
20712071+--- a/wokkel/test/test_generic.py
20722072++++ b/wokkel/test/test_generic.py
20732073+@@ -7,19 +7,12 @@ Tests for L{wokkel.generic}.
20742074+20752075+ from __future__ import division, absolute_import
20762076+20772077+-import re
20782078+-
20792079+ from zope.interface.verify import verifyObject
20802080+20812081+-from twisted.python import deprecate
20822082+-from twisted.python.compat import unicode
20832083+ from twisted.trial import unittest
20842084+-from twisted.trial.util import suppress as SUPPRESS
20852085+ from twisted.words.xish import domish
20862086+ from twisted.words.protocols.jabber.jid import JID
20872087+20882088+-from incremental import Version
20892089+-
20902090+ from wokkel import generic
20912091+ from wokkel.iwokkel import IDisco
20922092+ from wokkel.test.helpers import XmlStreamStub
20932093+@@ -66,11 +59,11 @@ class VersionHandlerTest(unittest.TestCase):
20942094+ elements = list(domish.generateElementsQNamed(response.query.children,
20952095+ 'name', NS_VERSION))
20962096+ self.assertEquals(1, len(elements))
20972097+- self.assertEquals('Test', unicode(elements[0]))
20982098++ self.assertEquals('Test', str(elements[0]))
20992099+ elements = list(domish.generateElementsQNamed(response.query.children,
21002100+ 'version', NS_VERSION))
21012101+ self.assertEquals(1, len(elements))
21022102+- self.assertEquals('0.1.0', unicode(elements[0]))
21032103++ self.assertEquals('0.1.0', str(elements[0]))
21042104+21052105+21062106+21072107+@@ -314,67 +307,3 @@ class RequestTest(unittest.TestCase):
21082108+21092109+ request = SetRequest()
21102110+ self.assertEqual('set', request.stanzaType)
21112111+-
21122112+-
21132113+-
21142114+-class PrepareIDNNameTests(unittest.TestCase):
21152115+- """
21162116+- Tests for L{wokkel.generic.prepareIDNName}.
21172117+- """
21182118+-
21192119+- suppress = [SUPPRESS(category=DeprecationWarning,
21202120+- message=re.escape(
21212121+- deprecate.getDeprecationWarningString(
21222122+- generic.prepareIDNName,
21232123+- Version("wokkel", 18, 0, 0),
21242124+- replacement="unicode.encode('idna')")))]
21252125+-
21262126+-
21272127+- def test_deprecated(self):
21282128+- """
21292129+- prepareIDNName is deprecated.
21302130+- """
21312131+- self.callDeprecated((Version("wokkel", 18, 0, 0),
21322132+- "unicode.encode('idna')"),
21332133+- generic.prepareIDNName, ("example.com"))
21342134+- test_deprecated.suppress = []
21352135+-
21362136+-
21372137+- def test_unicode(self):
21382138+- """
21392139+- A unicode all-ASCII name is converted to an ASCII byte string.
21402140+- """
21412141+- name = u"example.com"
21422142+- result = generic.prepareIDNName(name)
21432143+- self.assertEqual(b"example.com", result)
21442144+-
21452145+-
21462146+- def test_unicodeNonASCII(self):
21472147+- """
21482148+- A unicode with non-ASCII is converted to its ACE equivalent.
21492149+- """
21502150+- name = u"\u00e9chec.example.com"
21512151+- result = generic.prepareIDNName(name)
21522152+- self.assertEqual(b"xn--chec-9oa.example.com", result)
21532153+-
21542154+-
21552155+- def test_unicodeHalfwidthIdeographicFullStop(self):
21562156+- """
21572157+- Exotic dots in unicode names are converted to Full Stop.
21582158+- """
21592159+- name = u"\u00e9chec.example\uff61com"
21602160+- result = generic.prepareIDNName(name)
21612161+- self.assertEqual(b"xn--chec-9oa.example.com", result)
21622162+-
21632163+-
21642164+- def test_unicodeTrailingDot(self):
21652165+- """
21662166+- Unicode names with trailing dots retain the trailing dot.
21672167+-
21682168+- L{encodings.idna.ToASCII} doesn't allow the empty string as the input,
21692169+- hence the implementation needs to strip a trailing dot, and re-add it
21702170+- after encoding the labels.
21712171+- """
21722172+- name = u"example.com."
21732173+- result = generic.prepareIDNName(name)
21742174+- self.assertEqual(b"example.com.", result)
21752175+diff --git a/wokkel/test/test_muc.py b/wokkel/test/test_muc.py
21762176+index f690d05..282a8a1 100644
21772177+--- a/wokkel/test/test_muc.py
21782178++++ b/wokkel/test/test_muc.py
21792179+@@ -14,7 +14,6 @@ from zope.interface import verify
21802180+21812181+ from twisted.trial import unittest
21822182+ from twisted.internet import defer, task
21832183+-from twisted.python.compat import iteritems, unicode
21842184+ from twisted.words.xish import domish, xpath
21852185+ from twisted.words.protocols.jabber.jid import JID
21862186+ from twisted.words.protocols.jabber.error import StanzaError
21872187+@@ -81,7 +80,7 @@ class StatusCodeTest(unittest.TestCase):
21882188+ 332: 'removed-shutdown',
21892189+ }
21902190+21912191+- for code, condition in iteritems(codes):
21922192++ for code, condition in codes.items():
21932193+ constantName = condition.replace('-', '_').upper()
21942194+ self.assertEqual(getattr(muc.STATUS_CODE, constantName),
21952195+ muc.STATUS_CODE.lookupByValue(code))
21962196+@@ -757,7 +756,7 @@ class MUCClientProtocolTest(unittest.TestCase):
21972197+ self.assertEquals('message', message.name)
21982198+ self.assertEquals(self.roomJID.full(), message.getAttribute('to'))
21992199+ self.assertEquals('groupchat', message.getAttribute('type'))
22002200+- self.assertEquals(u'This is a test', unicode(message.body))
22012201++ self.assertEquals(u'This is a test', str(message.body))
22022202+22032203+22042204+ def test_chat(self):
22052205+@@ -773,7 +772,7 @@ class MUCClientProtocolTest(unittest.TestCase):
22062206+ self.assertEquals('message', message.name)
22072207+ self.assertEquals(otherOccupantJID.full(), message.getAttribute('to'))
22082208+ self.assertEquals('chat', message.getAttribute('type'))
22092209+- self.assertEquals(u'This is a test', unicode(message.body))
22102210++ self.assertEquals(u'This is a test', str(message.body))
22112211+22122212+22132213+ def test_subject(self):
22142214+@@ -787,7 +786,7 @@ class MUCClientProtocolTest(unittest.TestCase):
22152215+ self.assertEquals('message', message.name)
22162216+ self.assertEquals(self.roomJID.full(), message.getAttribute('to'))
22172217+ self.assertEquals('groupchat', message.getAttribute('type'))
22182218+- self.assertEquals(u'This is a test', unicode(message.subject))
22192219++ self.assertEquals(u'This is a test', str(message.subject))
22202220+22212221+22222222+ def test_invite(self):
22232223+@@ -806,7 +805,7 @@ class MUCClientProtocolTest(unittest.TestCase):
22242224+ self.assertEquals(muc.NS_MUC_USER, message.x.invite.uri)
22252225+ self.assertEquals(invitee.full(), message.x.invite.getAttribute('to'))
22262226+ self.assertEquals(muc.NS_MUC_USER, message.x.invite.reason.uri)
22272227+- self.assertEquals(u'This is a test', unicode(message.x.invite.reason))
22282228++ self.assertEquals(u'This is a test', str(message.x.invite.reason))
22292229+22302230+22312231+ def test_getRegisterForm(self):
22322232+@@ -1399,7 +1398,7 @@ class MUCClientProtocolTest(unittest.TestCase):
22332233+ nodes = xpath.queryForNodes(query, iq)
22342234+ self.assertNotIdentical(None, nodes, 'Bad configure request')
22352235+ destroy = nodes[0]
22362236+- self.assertEquals('Time to leave', unicode(destroy.reason))
22372237++ self.assertEquals('Time to leave', str(destroy.reason))
22382238+22392239+ response = toResponse(iq, 'result')
22402240+ self.stub.send(response)
22412241+diff --git a/wokkel/test/test_server.py b/wokkel/test/test_server.py
22422242+index 3e3c923..1efb6e5 100644
22432243+--- a/wokkel/test/test_server.py
22442244++++ b/wokkel/test/test_server.py
22452245+@@ -8,7 +8,11 @@ Tests for L{wokkel.server}.
22462246+ from __future__ import division, absolute_import
22472247+ from twisted.internet import defer
22482248+ from twisted.python import failure
22492249+-from twisted.test.proto_helpers import StringTransport
22502250++try:
22512251++ from twisted.internet.testing import StringTransport
22522252++except ImportError:
22532253++ from twisted.test.proto_helpers import StringTransport
22542254++
22552255+ from twisted.trial import unittest
22562256+ from twisted.words.protocols.jabber import error, jid, xmlstream
22572257+ from twisted.words.xish import domish
22582258+diff --git a/wokkel/test/test_shim.py b/wokkel/test/test_shim.py
22592259+index ded4679..d3b76cf 100644
22602260+--- a/wokkel/test/test_shim.py
22612261++++ b/wokkel/test/test_shim.py
22622262+@@ -9,7 +9,6 @@ Tests for {wokkel.shim}.
22632263+22642264+ from __future__ import division, absolute_import
22652265+22662266+-from twisted.python.compat import unicode
22672267+ from twisted.trial import unittest
22682268+22692269+ from wokkel import shim
22702270+@@ -36,7 +35,7 @@ class HeadersTest(unittest.TestCase):
22712271+ self.assertEquals(NS_SHIM, header.uri)
22722272+ self.assertEquals('header', header.name)
22732273+ self.assertEquals('Urgency', header['name'])
22742274+- self.assertEquals('high', unicode(header))
22752275++ self.assertEquals('high', str(header))
22762276+22772277+22782278+ def test_headerRepeated(self):
22792279+@@ -47,7 +46,7 @@ class HeadersTest(unittest.TestCase):
22802280+ ('Collection', 'node2')])
22812281+ elements = list(headers.elements())
22822282+ self.assertEquals(2, len(elements))
22832283+- collections = set((unicode(element) for element in elements
22842284++ collections = set((str(element) for element in elements
22852285+ if element['name'] == 'Collection'))
22862286+ self.assertIn('node1', collections)
22872287+ self.assertIn('node2', collections)
22882288+diff --git a/wokkel/test/test_xmppim.py b/wokkel/test/test_xmppim.py
22892289+index faab8ed..0d4fdbf 100644
22902290+--- a/wokkel/test/test_xmppim.py
22912291++++ b/wokkel/test/test_xmppim.py
22922292+@@ -9,7 +9,6 @@ from __future__ import division, absolute_import
22932293+22942294+ from twisted.internet import defer
22952295+ from twisted.trial import unittest
22962296+-from twisted.python.compat import unicode
22972297+ from twisted.words.protocols.jabber import error
22982298+ from twisted.words.protocols.jabber.jid import JID
22992299+ from twisted.words.protocols.jabber.xmlstream import toResponse
23002300+@@ -55,7 +54,7 @@ class PresenceClientProtocolTest(unittest.TestCase):
23012301+ self.assertEquals(None, presence.uri)
23022302+ self.assertEquals("user@example.com", presence.getAttribute('to'))
23032303+ self.assertEquals("unavailable", presence.getAttribute('type'))
23042304+- self.assertEquals("Disconnected", unicode(presence.status))
23052305++ self.assertEquals("Disconnected", str(presence.status))
23062306+23072307+ def test_unavailableBroadcast(self):
23082308+ """
23092309+@@ -298,9 +297,9 @@ class PresenceProtocolTest(unittest.TestCase):
23102310+ element = self.output[-1]
23112311+ self.assertEquals("user@example.com", element.getAttribute('to'))
23122312+ self.assertIdentical(None, element.getAttribute('type'))
23132313+- self.assertEquals(u'chat', unicode(element.show))
23142314+- self.assertEquals(u'Talk to me!', unicode(element.status))
23152315+- self.assertEquals(u'50', unicode(element.priority))
23162316++ self.assertEquals(u'chat', str(element.show))
23172317++ self.assertEquals(u'Talk to me!', str(element.status))
23182318++ self.assertEquals(u'50', str(element.priority))
23192319+23202320+ def test_availableLanguages(self):
23212321+ """
23222322+@@ -314,19 +313,19 @@ class PresenceProtocolTest(unittest.TestCase):
23232323+ element = self.output[-1]
23242324+ self.assertEquals("user@example.com", element.getAttribute('to'))
23252325+ self.assertIdentical(None, element.getAttribute('type'))
23262326+- self.assertEquals(u'chat', unicode(element.show))
23272327++ self.assertEquals(u'chat', str(element.show))
23282328+23292329+ statuses = {}
23302330+ for status in element.elements():
23312331+ if status.name == 'status':
23322332+ lang = status.getAttribute((NS_XML, 'lang'))
23332333+- statuses[lang] = unicode(status)
23342334++ statuses[lang] = str(status)
23352335+23362336+ self.assertIn(None, statuses)
23372337+ self.assertEquals(u'Talk to me!', statuses[None])
23382338+ self.assertIn('nl', statuses)
23392339+ self.assertEquals(u'Praat met me!', statuses['nl'])
23402340+- self.assertEquals(u'50', unicode(element.priority))
23412341++ self.assertEquals(u'50', str(element.priority))
23422342+23432343+23442344+ def test_availableSender(self):
23452345+@@ -363,7 +362,7 @@ class PresenceProtocolTest(unittest.TestCase):
23462346+ self.assertEquals(None, element.uri)
23472347+ self.assertEquals("user@example.com", element.getAttribute('to'))
23482348+ self.assertEquals("unavailable", element.getAttribute('type'))
23492349+- self.assertEquals("Disconnected", unicode(element.status))
23502350++ self.assertEquals("Disconnected", str(element.status))
23512351+23522352+23532353+ def test_unavailableBroadcast(self):
23542354+@@ -568,7 +567,7 @@ class RosterItemTest(unittest.TestCase):
23552355+ foundGroups = set()
23562356+ for child in element.elements():
23572357+ if child.uri == NS_ROSTER and child.name == 'group':
23582358+- foundGroups.add(unicode(child))
23592359++ foundGroups.add(str(child))
23602360+23612361+ self.assertEqual(groups, foundGroups)
23622362+23632363+diff --git a/wokkel/xmppim.py b/wokkel/xmppim.py
23642364+index e6af929..683577b 100644
23652365+--- a/wokkel/xmppim.py
23662366++++ b/wokkel/xmppim.py
23672367+@@ -15,7 +15,6 @@ from __future__ import division, absolute_import
23682368+ import warnings
23692369+23702370+ from twisted.internet import defer
23712371+-from twisted.python.compat import iteritems, itervalues, unicode
23722372+ from twisted.words.protocols.jabber import error
23732373+ from twisted.words.protocols.jabber.jid import JID
23742374+ from twisted.words.xish import domish
23752375+@@ -48,20 +47,20 @@ class AvailablePresence(Presence):
23762376+ self.addElement('show', content=show)
23772377+23782378+ if statuses is not None:
23792379+- for lang, status in iteritems(statuses):
23802380++ for lang, status in statuses.items():
23812381+ s = self.addElement('status', content=status)
23822382+ if lang:
23832383+ s[(NS_XML, "lang")] = lang
23842384+23852385+ if priority != 0:
23862386+- self.addElement('priority', content=unicode(int(priority)))
23872387++ self.addElement('priority', content=str(int(priority)))
23882388+23892389+ class UnavailablePresence(Presence):
23902390+ def __init__(self, to=None, statuses=None):
23912391+ Presence.__init__(self, to, type='unavailable')
23922392+23932393+ if statuses is not None:
23942394+- for lang, status in iteritems(statuses):
23952395++ for lang, status in statuses.items():
23962396+ s = self.addElement('status', content=status)
23972397+ if lang:
23982398+ s[(NS_XML, "lang")] = lang
23992399+@@ -76,7 +75,7 @@ class PresenceClientProtocol(XMPPHandler):
24002400+ for element in presence.elements():
24012401+ if element.name == 'status':
24022402+ lang = element.getAttribute((NS_XML, 'lang'))
24032403+- text = unicode(element)
24042404++ text = str(element)
24052405+ statuses[lang] = text
24062406+ return statuses
24072407+24082408+@@ -92,14 +91,14 @@ class PresenceClientProtocol(XMPPHandler):
24092409+ def _onPresenceAvailable(self, presence):
24102410+ entity = JID(presence["from"])
24112411+24122412+- show = unicode(presence.show or '')
24132413++ show = str(presence.show or '')
24142414+ if show not in ['away', 'xa', 'chat', 'dnd']:
24152415+ show = None
24162416+24172417+ statuses = self._getStatuses(presence)
24182418+24192419+ try:
24202420+- priority = int(unicode(presence.priority or '')) or 0
24212421++ priority = int(str(presence.priority or '')) or 0
24222422+ except ValueError:
24232423+ priority = 0
24242424+24252425+@@ -133,14 +132,14 @@ class PresenceClientProtocol(XMPPHandler):
24262426+ @type entity: {JID}
24272427+ @param show: detailed presence information. One of C{'away'}, C{'xa'},
24282428+ C{'chat'}, C{'dnd'} or C{None}.
24292429+- @type show: C{str} or C{NoneType}
24302430++ @type show: L{str} or C{NoneType}
24312431+ @param statuses: dictionary of natural language descriptions of the
24322432+ availability status, keyed by the language
24332433+ descriptor. A status without a language
24342434+ specified, is keyed with C{None}.
24352435+- @type statuses: C{dict}
24362436++ @type statuses: L{dict}
24372437+ @param priority: priority level of the resource.
24382438+- @type priority: C{int}
24392439++ @type priority: L{int}
24402440+ """
24412441+24422442+ def unavailableReceived(self, entity, statuses=None):
24432443+@@ -153,7 +152,7 @@ class PresenceClientProtocol(XMPPHandler):
24442444+ availability status, keyed by the language
24452445+ descriptor. A status without a language
24462446+ specified, is keyed with C{None}.
24472447+- @type statuses: C{dict}
24482448++ @type statuses: L{dict}
24492449+ """
24502450+24512451+ def subscribedReceived(self, entity):
24522452+@@ -196,14 +195,14 @@ class PresenceClientProtocol(XMPPHandler):
24532453+ @type entity: {JID}
24542454+ @param show: optional detailed presence information. One of C{'away'},
24552455+ C{'xa'}, C{'chat'}, C{'dnd'}.
24562456+- @type show: C{str}
24572457++ @type show: L{str}
24582458+ @param statuses: dictionary of natural language descriptions of the
24592459+ availability status, keyed by the language
24602460+ descriptor. A status without a language
24612461+ specified, is keyed with C{None}.
24622462+- @type statuses: C{dict}
24632463++ @type statuses: L{dict}
24642464+ @param priority: priority level of the resource.
24652465+- @type priority: C{int}
24662466++ @type priority: L{int}
24672467+ """
24682468+ self.send(AvailablePresence(entity, show, statuses, priority))
24692469+24702470+@@ -217,7 +216,7 @@ class PresenceClientProtocol(XMPPHandler):
24712471+ availability status, keyed by the language
24722472+ descriptor. A status without a language
24732473+ specified, is keyed with C{None}.
24742474+- @type statuses: C{dict}
24752475++ @type statuses: L{dict}
24762476+ """
24772477+ self.send(UnavailablePresence(entity, statuses))
24782478+24792479+@@ -275,19 +274,19 @@ class AvailabilityPresence(BasePresence):
24802480+ L{SubscriptionPresence}).
24812481+24822482+ @ivar available: The availability being communicated.
24832483+- @type available: C{bool}
24842484++ @type available: L{bool}
24852485+ @ivar show: More specific availability. Can be one of C{'chat'}, C{'away'},
24862486+ C{'xa'}, C{'dnd'} or C{None}.
24872487+- @type show: C{str} or C{NoneType}
24882488++ @type show: L{str} or C{NoneType}
24892489+ @ivar statuses: Natural language texts to detail the (un)availability.
24902490+ These are represented as a mapping from language code
24912491+- (C{str} or C{None}) to the corresponding text (C{unicode}).
24922492++ (L{str} or C{None}) to the corresponding text (L{str}).
24932493+ If the key is C{None}, the associated text is in the
24942494+ default language.
24952495+- @type statuses: C{dict}
24962496++ @type statuses: L{dict}
24972497+ @ivar priority: Priority level for this resource. Must be between -128 and
24982498+ 127. Defaults to 0.
24992499+- @type priority: C{int}
25002500++ @type priority: L{int}
25012501+ """
25022502+25032503+ childParsers = {(None, 'show'): '_childParser_show',
25042504+@@ -309,7 +308,7 @@ class AvailabilityPresence(BasePresence):
25052505+ if None in self.statuses:
25062506+ return self.statuses[None]
25072507+ elif self.statuses:
25082508+- for status in itervalues(self.status):
25092509++ for status in self.status.values():
25102510+ return status
25112511+ else:
25122512+ return None
25132513+@@ -318,20 +317,20 @@ class AvailabilityPresence(BasePresence):
25142514+25152515+25162516+ def _childParser_show(self, element):
25172517+- show = unicode(element)
25182518++ show = str(element)
25192519+ if show in ('chat', 'away', 'xa', 'dnd'):
25202520+ self.show = show
25212521+25222522+25232523+ def _childParser_status(self, element):
25242524+ lang = element.getAttribute((NS_XML, 'lang'), None)
25252525+- text = unicode(element)
25262526++ text = str(element)
25272527+ self.statuses[lang] = text
25282528+25292529+25302530+ def _childParser_priority(self, element):
25312531+ try:
25322532+- self.priority = int(unicode(element))
25332533++ self.priority = int(str(element))
25342534+ except ValueError:
25352535+ pass
25362536+25372537+@@ -353,9 +352,9 @@ class AvailabilityPresence(BasePresence):
25382538+ if self.show in ('chat', 'away', 'xa', 'dnd'):
25392539+ presence.addElement('show', content=self.show)
25402540+ if self.priority != 0:
25412541+- presence.addElement('priority', content=unicode(self.priority))
25422542++ presence.addElement('priority', content=str(self.priority))
25432543+25442544+- for lang, text in iteritems(self.statuses):
25452545++ for lang, text in self.statuses.items():
25462546+ status = presence.addElement('status', content=text)
25472547+ if lang:
25482548+ status[(NS_XML, 'lang')] = lang
25492549+@@ -400,7 +399,7 @@ class BasePresenceProtocol(XMPPHandler):
25502550+25512551+ @cvar presenceTypeParserMap: Maps presence stanza types to their respective
25522552+ stanza parser classes (derived from L{Stanza}).
25532553+- @type presenceTypeParserMap: C{dict}
25542554++ @type presenceTypeParserMap: L{dict}
25552555+ """
25562556+25572557+ presenceTypeParserMap = {}
25582558+@@ -515,15 +514,15 @@ class PresenceProtocol(BasePresenceProtocol):
25592559+25602560+ @param show: Optional detailed presence information. One of C{'away'},
25612561+ C{'xa'}, C{'chat'}, C{'dnd'}.
25622562+- @type show: C{str}
25632563++ @type show: L{str}
25642564+25652565+ @param statuses: Mapping of natural language descriptions of the
25662566+ availability status, keyed by the language descriptor. A status
25672567+ without a language specified, is keyed with C{None}.
25682568+- @type statuses: C{dict}
25692569++ @type statuses: L{dict}
25702570+25712571+ @param priority: priority level of the resource.
25722572+- @type priority: C{int}
25732573++ @type priority: L{int}
25742574+ """
25752575+ presence = AvailabilityPresence(recipient=recipient, sender=sender,
25762576+ show=show, statuses=statuses,
25772577+@@ -541,7 +540,7 @@ class PresenceProtocol(BasePresenceProtocol):
25782578+ @param statuses: dictionary of natural language descriptions of the
25792579+ availability status, keyed by the language descriptor. A status
25802580+ without a language specified, is keyed with C{None}.
25812581+- @type statuses: C{dict}
25822582++ @type statuses: L{dict}
25832583+ """
25842584+ presence = AvailabilityPresence(recipient=recipient, sender=sender,
25852585+ available=False, statuses=statuses)
25862586+@@ -617,25 +616,25 @@ class RosterItem(object):
25872587+ @ivar entity: The JID of the contact.
25882588+ @type entity: L{JID}
25892589+ @ivar name: The associated nickname for this contact.
25902590+- @type name: C{unicode}
25912591++ @type name: L{str}
25922592+ @ivar subscriptionTo: Subscription state to contact's presence. If C{True},
25932593+ the roster owner is subscribed to the presence
25942594+ information of the contact.
25952595+- @type subscriptionTo: C{bool}
25962596++ @type subscriptionTo: L{bool}
25972597+ @ivar subscriptionFrom: Contact's subscription state. If C{True}, the
25982598+ contact is subscribed to the presence information
25992599+ of the roster owner.
26002600+- @type subscriptionFrom: C{bool}
26012601++ @type subscriptionFrom: L{bool}
26022602+ @ivar pendingOut: Whether the subscription request to this contact is
26032603+ pending.
26042604+- @type pendingOut: C{bool}
26052605++ @type pendingOut: L{bool}
26062606+ @ivar groups: Set of groups this contact is categorized in. Groups are
26072607+- represented by an opaque identifier of type C{unicode}.
26082608+- @type groups: C{set}
26092609++ represented by an opaque identifier of type L{str}.
26102610++ @type groups: L{set}
26112611+ @ivar approved: Signals pre-approved subscription.
26122612+- @type approved: C{bool}
26132613++ @type approved: L{bool}
26142614+ @ivar remove: Signals roster item removal.
26152615+- @type remove: C{bool}
26162616++ @type remove: L{bool}
26172617+ """
26182618+26192619+ __subscriptionStates = {(False, False): None,
26202620+@@ -755,7 +754,7 @@ class RosterItem(object):
26212621+ item.approved = element.getAttribute('approved') in ('true', '1')
26222622+ for subElement in domish.generateElementsQNamed(element.children,
26232623+ 'group', NS_ROSTER):
26242624+- item.groups.add(unicode(subElement))
26252625++ item.groups.add(str(subElement))
26262626+ return item
26272627+26282628+26292629+@@ -771,7 +770,7 @@ class RosterRequest(Request):
26302630+ retrieving the roster as a delta from a known cached version. This
26312631+ should only be set if the recipient is known to support roster
26322632+ versioning.
26332633+- @type version: C{unicode}
26342634++ @type version: L{str}
26352635+26362636+ @ivar rosterSet: If set, this is a roster set request. This flag is used
26372637+ to make sure some attributes of the roster item are not rendered by
26382638+@@ -821,7 +820,7 @@ class Roster(dict):
26392639+ identifier for this version of the roster.
26402640+26412641+ @ivar version: Roster version identifier.
26422642+- @type version: C{unicode}.
26432643++ @type version: L{str}.
26442644+ """
26452645+26462646+ version = None
26472647+@@ -892,7 +891,7 @@ class RosterClientProtocol(XMPPHandler, IQHandlerMixin):
26482648+ known to support roster versioning. If there is no (valid) cached
26492649+ version of the roster, but roster versioning is desired,
26502650+ C{version} should be set to the empty string (C{u''}).
26512651+- @type version: C{unicode}
26522652++ @type version: L{str}
26532653+26542654+ @return: Roster as a mapping from L{JID} to L{RosterItem}.
26552655+ @rtype: L{twisted.internet.defer.Deferred}
26562656+@@ -1023,11 +1022,11 @@ class Message(Stanza):
26572657+26582658+26592659+ def _childParser_body(self, element):
26602660+- self.body = unicode(element)
26612661++ self.body = str(element)
26622662+26632663+26642664+ def _childParser_subject(self, element):
26652665+- self.subject = unicode(element)
26662666++ self.subject = str(element)
26672667+26682668+26692669+ def toElement(self):
26702670+--
26712671+2.44.1
···33333434 ]
3535 ++ lib.optionals (stdenv.buildPlatform.config != stdenv.hostPlatform.config) [
3636+ # There's a fallback path for BSDs.
3737+ "--with-sysdep-procselfexe=${
3838+ if stdenv.hostPlatform.isLinux then
3939+ "/proc/self/exe"
4040+ else if stdenv.hostPlatform.isSunOS then
4141+ "/proc/self/path/a.out"
4242+ else
4343+ "none"
4444+ }"
3645 # ./configure: sysdep posixspawnearlyreturn cannot be autodetected
3746 # when cross-compiling. Please manually provide a value with the
3847 # --with-sysdep-posixspawnearlyreturn=yes|no|... option.
+1
pkgs/top-level/aliases.nix
···773773 svn_all_fast_export = svn-all-fast-export;
774774 topGit = top-git;
775775 }; # Added 2021-01-14
776776+ github-copilot-cli = throw "'github-copilot-cli' has been removed because GitHub has replaced it with 'gh-copilot'."; # Added 2025-06-01
776777 givaro_3 = throw "'givaro_3' has been removed as it is end-of-life. Consider using the up-to-date 'givaro' instead"; # Added 2025-05-07
777778 givaro_3_7 = throw "'givaro_3_7' has been removed as it is end-of-life. Consider using the up-to-date 'givaro' instead"; # Added 2025-05-07
778779 gkraken = throw "'gkraken' has been deprecated by upstream. Consider using the replacement 'coolercontrol' instead."; # Added 2024-11-22