···4445 - uses: cachix/install-nix-action@526118121621777ccd86f79b04685a9319637641 # v31
4647+ - uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
48+ with:
49+ # This cache is for the nixpkgs repo checks and should not be trusted or used elsewhere.
50+ name: nixpkgs-ci
51+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
52+53 - name: Build shell
54 run: nix-build untrusted/ci -A shell
···32 with:
33 extra_nix_config: sandbox = true
3435+ - uses: cachix/cachix-action@0fc020193b5a1fa3ac4575aa3a7d3aa6a35435ad # v16
36+ with:
37+ # This cache is for the nixpkgs repo checks and should not be trusted or used elsewhere.
38+ name: nixpkgs-ci
39+ authToken: "${{ secrets.CACHIX_AUTH_TOKEN }}"
40+41 - name: Building Nixpkgs lib-tests
42 run: |
43 nix-build untrusted/ci -A lib-tests
···28 - 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)
29 - Packages that used to depend on Mesa for libgbm or libdri should use `libgbm` or `dri-pkgconfig-stub` as inputs, respectively
30000031- 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.
3233- Emacs has been updated to 30.1.
···28 - 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)
29 - Packages that used to depend on Mesa for libgbm or libdri should use `libgbm` or `dri-pkgconfig-stub` as inputs, respectively
3031+- GNU Taler has been updated to version 1.0.
32+ This marks a significant milestone as the GNU Taler payment system is now available in Swiss Francs for individuals and businesses in Switzerland.
33+ For more details, see the [upstream release notes](https://www.taler.net/en/news/2025-01.html).
34+35- 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.
3637- Emacs has been updated to 30.1.
···25 "secmod-eddsa"
26 "secmod-rsa"
27 ];
0028in
2930{
···44 options = {
45 # TODO: do we want this to be a sub-attribute or only define the exchange set of options here
46 exchange = {
47- AML_THRESHOLD = lib.mkOption {
00000048 type = lib.types.str;
49- default = "${cfgTaler.settings.taler.CURRENCY}:1000000";
50- defaultText = "1000000 in {option}`CURRENCY`";
51- description = "Monthly transaction volume until an account is considered suspicious and flagged for AML review.";
0052 };
53 DB = lib.mkOption {
54 type = lib.types.enum [ "postgres" ];
···131 after = [ "taler-exchange-httpd.service" ];
132 };
133134- # Taken from https://docs.taler.net/taler-exchange-manual.html#exchange-database-setup
135- # TODO: Why does aggregator need DELETE?
136- systemd.services."taler-${talerComponent}-dbinit".script =
137- let
138- deletePerm = name: lib.optionalString (name == "aggregator") ",DELETE";
139- dbScript = pkgs.writers.writeText "taler-exchange-db-permissions.sql" (
140- lib.pipe servicesDB [
141- (map (name: ''
142- GRANT SELECT,INSERT,UPDATE${deletePerm name} ON ALL TABLES IN SCHEMA exchange TO "taler-exchange-${name}";
143- GRANT USAGE ON SCHEMA exchange TO "taler-exchange-${name}";
144- ''))
145- lib.concatStrings
146- ]
147- );
148- in
149- ''
150- ${lib.getExe' cfg.package "taler-exchange-dbinit"}
151- psql -U taler-exchange-httpd -f ${dbScript}
152- '';
153 };
154}
···25 "secmod-eddsa"
26 "secmod-rsa"
27 ];
28+29+ configFile = config.environment.etc."taler/taler.conf".source;
30in
3132{
···46 options = {
47 # TODO: do we want this to be a sub-attribute or only define the exchange set of options here
48 exchange = {
49+ CURRENCY = lib.mkOption {
50+ type = lib.types.nonEmptyStr;
51+ description = ''
52+ The currency which the exchange will operate with. This cannot be changed later.
53+ '';
54+ };
55+ CURRENCY_ROUND_UNIT = lib.mkOption {
56 type = lib.types.str;
57+ default = "${cfg.settings.exchange.CURRENCY}:0.01";
58+ defaultText = "0.01 in {option}`CURRENCY`";
59+ description = ''
60+ Smallest amount in this currency that can be transferred using the underlying RTGS. For example: "EUR:0.01" or "JPY:1"
61+ '';
62 };
63 DB = lib.mkOption {
64 type = lib.types.enum [ "postgres" ];
···141 after = [ "taler-exchange-httpd.service" ];
142 };
143144+ systemd.services."taler-${talerComponent}-dbinit".script = ''
145+ ${lib.getExe' cfg.package "taler-exchange-dbinit"} -c ${configFile}
146+ '';
0000000000000000147 };
148}
+6-17
nixos/modules/services/finance/taler/merchant.nix
···17 "webhook"
18 "wirewatch"
19 "depositcheck"
20- "exchange"
21 ];
0022in
23{
24 imports = [
···88 path = [ cfg.package ];
89 };
9091- systemd.services."taler-${talerComponent}-dbinit".script =
92- let
93- # NOTE: not documented, but is necessary
94- dbScript = pkgs.writers.writeText "taler-merchant-db-permissions.sql" (
95- lib.concatStrings (
96- map (name: ''
97- GRANT SELECT,INSERT,UPDATE,DELETE ON ALL TABLES IN SCHEMA merchant TO "taler-merchant-${name}";
98- GRANT USAGE ON SCHEMA merchant TO "taler-merchant-${name}";
99- '') servicesDB
100- )
101- );
102- in
103- ''
104- ${lib.getExe' cfg.package "taler-merchant-dbinit"}
105- psql -U taler-${talerComponent}-httpd -f ${dbScript}
106- '';
107 };
108}
···21 postInstall = ''
22 chmod -R u+w $out/share
23 # Only include the files needed for runtime in the derivation
24- mv $out/share/php/${finalAttrs.pname}/{migrations,public,src,config,bin,templates,tests,translations,vendor,symfony.lock,composer.json,composer.lock} $out
25 # Save the upstream .env file for reference, but rename it so it is not loaded
26- mv $out/share/php/${finalAttrs.pname}/.env $out/env-upstream
27 rm -rf "$out/share"
28 '';
29
···21 postInstall = ''
22 chmod -R u+w $out/share
23 # Only include the files needed for runtime in the derivation
24+ mv $out/share/php/davis/{migrations,public,src,config,bin,templates,tests,translations,vendor,symfony.lock,composer.json,composer.lock} $out
25 # Save the upstream .env file for reference, but rename it so it is not loaded
26+ mv $out/share/php/davis/.env $out/env-upstream
27 rm -rf "$out/share"
28 '';
29
···49 # The package expect to find an `example-robot-data/robots` folder somewhere
50 # either in install prefix or in the sources
51 # where it can find the meshes for unit tests
52- preCheck = "ln -s source ../../${finalAttrs.pname}";
53 pythonImportsCheck = [ "example_robot_data" ];
5455 meta = with lib; {
···49 # The package expect to find an `example-robot-data/robots` folder somewhere
50 # either in install prefix or in the sources
51 # where it can find the meshes for unit tests
52+ preCheck = "ln -s source ../../example-robot-data";
53 pythonImportsCheck = [ "example_robot_data" ];
5455 meta = with lib; {
···19 runHook preInstall
2021 # https://gitlab.archlinux.org/archlinux/packaging/packages/fcitx5-material-color/-/blob/main/PKGBUILD?ref_type=heads#L16
22- install -Dm644 arrow.png radio.png -t $out/share/${finalAttrs.pname}/
23 for _variant in black blue brown deepPurple indigo orange pink red sakuraPink teal; do
24 _variant_name=Material-Color-$_variant
25 install -dm755 $_variant_name $out/share/fcitx5/themes/$_variant_name
···19 runHook preInstall
2021 # https://gitlab.archlinux.org/archlinux/packaging/packages/fcitx5-material-color/-/blob/main/PKGBUILD?ref_type=heads#L16
22+ install -Dm644 arrow.png radio.png -t $out/share/fcitx5-material-color/
23 for _variant in black blue brown deepPurple indigo orange pink red sakuraPink teal; do
24 _variant_name=Material-Color-$_variant
25 install -dm755 $_variant_name $out/share/fcitx5/themes/$_variant_name
+1-1
pkgs/by-name/fi/figma-linux/package.nix
···8283 postFixup = ''
84 substituteInPlace $out/share/applications/figma-linux.desktop \
85- --replace "Exec=/opt/figma-linux/figma-linux" "Exec=$out/bin/${finalAttrs.pname}"
86 '';
8788 meta = with lib; {
···8283 postFixup = ''
84 substituteInPlace $out/share/applications/figma-linux.desktop \
85+ --replace "Exec=/opt/figma-linux/figma-linux" "Exec=$out/bin/figma-linux"
86 '';
8788 meta = with lib; {
···1112stdenvNoCC.mkDerivation (finalAttrs: {
13 pname = "markdownlint-cli2";
14- version = "0.17.2";
1516 # upstream is not interested in including package-lock.json in the source
17 # https://github.com/DavidAnson/markdownlint-cli2/issues/198#issuecomment-1690529976
···19 # so use the tarball from the archlinux mirror
20 src = fetchurl {
21 url = "https://us.mirrors.cicku.me/archlinux/extra/os/x86_64/markdownlint-cli2-${finalAttrs.version}-1-any.pkg.tar.zst";
22- hash = "sha256-TuiLFP/XItJh5VQWdwCvXRQCVzmqst4Sxna0eLobEQ4=";
23 };
2425 nativeBuildInputs = [
···1112stdenvNoCC.mkDerivation (finalAttrs: {
13 pname = "markdownlint-cli2";
14+ version = "0.18.1";
1516 # upstream is not interested in including package-lock.json in the source
17 # https://github.com/DavidAnson/markdownlint-cli2/issues/198#issuecomment-1690529976
···19 # so use the tarball from the archlinux mirror
20 src = fetchurl {
21 url = "https://us.mirrors.cicku.me/archlinux/extra/os/x86_64/markdownlint-cli2-${finalAttrs.version}-1-any.pkg.tar.zst";
22+ hash = "sha256-M7qmhRDJGm2MhgS2oMfRrkLAst1Ye/rPCwP78UBbyyY=";
23 };
2425 nativeBuildInputs = [
···1+From 3161fec0b9ff9154dbd952c3481400118fabb744 Mon Sep 17 00:00:00 2001
2+From: Helmut Grohne <helmut.grohne@intenta.de>
3+Date: Thu, 21 Apr 2022 10:07:53 +0200
4+Subject: [PATCH] Add rudimentary support for modules property
5+6+In linux commit 6dd85ff178cd76851e2184b13e545f5a88d1be30, Linux Torvalds
7+changed "option modules" to plain "modules" since it was the only option
8+left. kconfiglib does not have much support for either besides parsing
9+it and suppressing warnings when it is applied to the 'MODULES' symbol.
10+Mirror this behaviour for the newer "modules" property.
11+12+Fixes: #106
13+---
14+ kconfiglib.py | 14 ++++++++++++++
15+ 1 file changed, 14 insertions(+)
16+17+diff --git a/kconfiglib.py b/kconfiglib.py
18+index c67895c..ccef123 100644
19+--- a/kconfiglib.py
20++++ b/kconfiglib.py
21+@@ -3263,6 +3263,20 @@ def _parse_props(self, node):
22+ else:
23+ self._parse_error("unrecognized option")
24+25++ elif t0 is _T_MODULES:
26++ # 'modules' formerly was 'option modules'. See above for why
27++ # and when it is ignored. It was changed in
28++ # linux commit 6dd85ff178cd76851e2184b13e545f5a88d1be30.
29++ if node.item is not self.modules:
30++ self._warn("the 'modules' property is not supported. Let "
31++ "me know if this is a problem for you, as it "
32++ "wouldn't be that hard to implement. Note that "
33++ "modules are supported -- Kconfiglib just "
34++ "assumes the symbol name MODULES, like older "
35++ "versions of the C implementation did when "
36++ "'modules' wasn't used.",
37++ self.filename, self.linenr)
38++
39+ elif t0 is _T_OPTIONAL:
40+ if node.item.__class__ is not Choice:
41+ self._parse_error('"optional" is only valid for choices')
···14 sha256 = "0g690bk789hsry34y4ahvly5c8w8imca90ss4njfqf7m2qicrlmy";
15 };
160000017 # doesnt work out of the box but might be possible
18 doCheck = false;
19
···14 sha256 = "0g690bk789hsry34y4ahvly5c8w8imca90ss4njfqf7m2qicrlmy";
15 };
1617+ patches = [
18+ # see https://github.com/ulfalizer/Kconfiglib/pull/119
19+ ./0001-Add-rudimentary-support-for-modules-property.patch
20+ ];
21+22 # doesnt work out of the box but might be possible
23 doCheck = false;
24
···1+From 6b3ab4a94e4d498cdabd5aac6b749031abd785c8 Mon Sep 17 00:00:00 2001
2+From: Ralph Meijer <ralphm@ik.nu>
3+Date: Thu, 18 Jul 2024 19:04:47 +0200
4+Subject: [PATCH] Remove py2 compat
5+6+Co-authored-by: OPNA2608 <opna2608@protonmail.com>
7+---
8+ setup.py | 11 ++-
9+ wokkel/component.py | 13 ++-
10+ wokkel/data_form.py | 70 ++++++----------
11+ wokkel/delay.py | 2 +-
12+ wokkel/disco.py | 51 ++++++------
13+ wokkel/formats.py | 20 ++---
14+ wokkel/generic.py | 19 +----
15+ wokkel/iwokkel.py | 150 +++++++++++++++++-----------------
16+ wokkel/muc.py | 67 ++++++++-------
17+ wokkel/pubsub.py | 55 ++++++-------
18+ wokkel/server.py | 17 ++--
19+ wokkel/shim.py | 5 +-
20+ wokkel/subprotocols.py | 13 ++-
21+ wokkel/test/helpers.py | 5 +-
22+ wokkel/test/test_client.py | 3 +-
23+ wokkel/test/test_data_form.py | 89 +++++---------------
24+ wokkel/test/test_generic.py | 75 +----------------
25+ wokkel/test/test_muc.py | 13 ++-
26+ wokkel/test/test_server.py | 6 +-
27+ wokkel/test/test_shim.py | 5 +-
28+ wokkel/test/test_xmppim.py | 19 ++---
29+ wokkel/xmppim.py | 89 ++++++++++----------
30+ 22 files changed, 318 insertions(+), 479 deletions(-)
31+32+diff --git a/setup.py b/setup.py
33+index 8804fd9..f7f1e33 100755
34+--- a/setup.py
35++++ b/setup.py
36+@@ -40,11 +40,11 @@ setup(name='wokkel',
37+ license='MIT',
38+ platforms='any',
39+ classifiers=[
40+- 'Programming Language :: Python :: 2.7',
41+ 'Programming Language :: Python :: 3',
42+- 'Programming Language :: Python :: 3.4',
43+- 'Programming Language :: Python :: 3.5',
44+ 'Programming Language :: Python :: 3.6',
45++ 'Programming Language :: Python :: 3.7',
46++ 'Programming Language :: Python :: 3.8',
47++ 'Programming Language :: Python :: 3.9',
48+ ],
49+ packages=[
50+ 'wokkel',
51+@@ -60,16 +60,15 @@ setup(name='wokkel',
52+ install_requires=[
53+ 'incremental>=16.9.0',
54+ 'python-dateutil',
55++ 'Twisted[tls]>=16.4.0',
56+ ],
57+ extras_require={
58+- ":python_version<'3'": 'Twisted[tls]>=15.5.0',
59+- ":python_version>'3'": 'Twisted[tls]>=16.4.0',
60+ "dev": [
61+ "pyflakes",
62+ "coverage",
63++ "pydoctor",
64+ "sphinx",
65+ "towncrier",
66+ ],
67+- "dev:python_version<'3'": "pydoctor",
68+ },
69+ )
70+diff --git a/wokkel/component.py b/wokkel/component.py
71+index da48230..9410837 100644
72+--- a/wokkel/component.py
73++++ b/wokkel/component.py
74+@@ -12,7 +12,6 @@ from __future__ import division, absolute_import
75+ from twisted.application import service
76+ from twisted.internet import reactor
77+ from twisted.python import log
78+-from twisted.python.compat import unicode
79+ from twisted.words.protocols.jabber.jid import internJID as JID
80+ from twisted.words.protocols.jabber import component, error, xmlstream
81+ from twisted.words.xish import domish
82+@@ -105,7 +104,7 @@ class InternalComponent(xmlstream.XMPPHandlerCollection, service.Service):
83+ components of this type connect to a router in the same process. This
84+ allows for one-process XMPP servers.
85+86+- @ivar domains: Domains (as L{unicode}) this component will handle traffic
87++ @ivar domains: Domains (as L{str}) this component will handle traffic
88+ for.
89+ @type domains: L{set}
90+ """
91+@@ -177,7 +176,7 @@ class ListenComponentAuthenticator(xmlstream.ListenAuthenticator):
92+ Authenticator for accepting components.
93+94+ @ivar secret: The shared used to authorized incoming component connections.
95+- @type secret: L{unicode}.
96++ @type secret: L{str}.
97+ """
98+99+ namespace = NS_COMPONENT_ACCEPT
100+@@ -241,7 +240,7 @@ class ListenComponentAuthenticator(xmlstream.ListenAuthenticator):
101+ L{onHandshake}.
102+ """
103+ if (element.uri, element.name) == (self.namespace, 'handshake'):
104+- self.onHandshake(unicode(element))
105++ self.onHandshake(str(element))
106+ else:
107+ exc = error.StreamError('not-authorized')
108+ self.xmlstream.sendStreamError(exc)
109+@@ -257,7 +256,7 @@ class ListenComponentAuthenticator(xmlstream.ListenAuthenticator):
110+ be exchanged.
111+ """
112+ calculatedHash = xmlstream.hashPassword(self.xmlstream.sid,
113+- unicode(self.secret))
114++ str(self.secret))
115+ if handshake != calculatedHash:
116+ exc = error.StreamError('not-authorized', text='Invalid hash')
117+ self.xmlstream.sendStreamError(exc)
118+@@ -301,7 +300,7 @@ class Router(object):
119+120+ @param destination: Destination of the route to be added as a host name
121+ or L{None} for the default route.
122+- @type destination: L{unicode} or L{NoneType}
123++ @type destination: L{str} or L{NoneType}
124+125+ @param xs: XML Stream to register the route for.
126+ @type xs:
127+@@ -316,7 +315,7 @@ class Router(object):
128+ Remove a route.
129+130+ @param destination: Destination of the route that should be removed.
131+- @type destination: L{unicode}
132++ @type destination: L{str}
133+134+ @param xs: XML Stream to remove the route for.
135+ @type xs:
136+diff --git a/wokkel/data_form.py b/wokkel/data_form.py
137+index ed9c5fc..7f1c34c 100644
138+--- a/wokkel/data_form.py
139++++ b/wokkel/data_form.py
140+@@ -17,7 +17,6 @@ from __future__ import division, absolute_import
141+ from zope.interface import implementer
142+ from zope.interface.common import mapping
143+144+-from twisted.python.compat import iteritems, unicode, _PY3
145+ from twisted.words.protocols.jabber.jid import JID
146+ from twisted.words.xish import domish
147+148+@@ -51,9 +50,9 @@ class Option(object):
149+ Data Forms field option.
150+151+ @ivar value: Value of this option.
152+- @type value: L{unicode}
153++ @type value: L{str}
154+ @ivar label: Optional label for this option.
155+- @type label: L{unicode} or L{NoneType}
156++ @type label: L{str} or L{NoneType}
157+ """
158+159+ def __init__(self, value, label=None):
160+@@ -91,7 +90,7 @@ class Option(object):
161+ raise Error("Option has no value")
162+163+ label = element.getAttribute('label')
164+- return Option(unicode(valueElements[0]), label)
165++ return Option(str(valueElements[0]), label)
166+167+168+ class Field(object):
169+@@ -108,15 +107,15 @@ class Field(object):
170+ @ivar var: Field name. Optional if C{fieldType} is C{'fixed'}.
171+ @type var: L{str}
172+ @ivar label: Human readable label for this field.
173+- @type label: L{unicode}
174++ @type label: L{str}
175+ @ivar values: The values for this field, for multi-valued field
176+- types, as a list of L{bool}, L{unicode} or L{JID}.
177++ types, as a list of L{bool}, L{str} or L{JID}.
178+ @type values: L{list}
179+ @ivar options: List of possible values to choose from in a response
180+ to this form as a list of L{Option}s.
181+ @type options: L{list}
182+ @ivar desc: Human readable description for this field.
183+- @type desc: L{unicode}
184++ @type desc: L{str}
185+ @ivar required: Whether the field is required to be provided in a
186+ response to this form.
187+ @type required: L{bool}
188+@@ -147,7 +146,7 @@ class Field(object):
189+ try:
190+ self.options = [Option(optionValue, optionLabel)
191+ for optionValue, optionLabel
192+- in iteritems(options)]
193++ in options.items()]
194+ except AttributeError:
195+ self.options = options or []
196+197+@@ -185,7 +184,7 @@ class Field(object):
198+199+ Sets C{value} as the only element of L{values}.
200+201+- @type value: L{bool}, L{unicode} or L{JID}
202++ @type value: L{bool}, L{str} or L{JID}
203+ """
204+ self.values = [value]
205+206+@@ -229,7 +228,7 @@ class Field(object):
207+ newValues = []
208+ for value in self.values:
209+ if self.fieldType == 'boolean':
210+- if isinstance(value, (str, unicode)):
211++ if isinstance(value, str):
212+ checkValue = value.lower()
213+ if not checkValue in ('0', '1', 'false', 'true'):
214+ raise ValueError("Not a boolean")
215+@@ -263,9 +262,9 @@ class Field(object):
216+217+ for value in self.values:
218+ if isinstance(value, bool):
219+- value = unicode(value).lower()
220++ value = str(value).lower()
221+ else:
222+- value = unicode(value)
223++ value = str(value)
224+225+ field.addElement('value', content=value)
226+227+@@ -288,7 +287,7 @@ class Field(object):
228+229+ @staticmethod
230+ def _parse_desc(field, element):
231+- desc = unicode(element)
232++ desc = str(element)
233+ if desc:
234+ field.desc = desc
235+236+@@ -305,7 +304,7 @@ class Field(object):
237+238+ @staticmethod
239+ def _parse_value(field, element):
240+- value = unicode(element)
241++ value = str(element)
242+ field.values.append(value)
243+244+245+@@ -313,9 +312,9 @@ class Field(object):
246+ def fromElement(element):
247+ field = Field(None)
248+249+- for eAttr, fAttr in iteritems({'type': 'fieldType',
250+- 'var': 'var',
251+- 'label': 'label'}):
252++ for eAttr, fAttr in {'type': 'fieldType',
253++ 'var': 'var',
254++ 'label': 'label'}.items():
255+ value = element.getAttribute(eAttr)
256+ if value:
257+ setattr(field, fAttr, value)
258+@@ -350,7 +349,7 @@ class Field(object):
259+260+ if 'options' in fieldDict:
261+ options = []
262+- for value, label in iteritems(fieldDict['options']):
263++ for value, label in fieldDict['options'].items():
264+ options.append(Option(value, label))
265+ kwargs['options'] = options
266+267+@@ -385,9 +384,9 @@ class Form(object):
268+ @type formType: L{str}
269+270+ @ivar title: Natural language title of the form.
271+- @type title: L{unicode}
272++ @type title: L{str}
273+274+- @ivar instructions: Natural language instructions as a list of L{unicode}
275++ @ivar instructions: Natural language instructions as a list of L{str}
276+ strings without line breaks.
277+ @type instructions: L{list}
278+279+@@ -497,7 +496,7 @@ class Form(object):
280+ C{fieldDefs}.
281+ @type filterUnknown: L{bool}
282+ """
283+- for name, value in iteritems(values):
284++ for name, value in values.items():
285+ fieldDict = {'var': name,
286+ 'type': None}
287+288+@@ -542,14 +541,14 @@ class Form(object):
289+290+ @staticmethod
291+ def _parse_title(form, element):
292+- title = unicode(element)
293++ title = str(element)
294+ if title:
295+ form.title = title
296+297+298+ @staticmethod
299+ def _parse_instructions(form, element):
300+- instructions = unicode(element)
301++ instructions = str(element)
302+ if instructions:
303+ form.instructions.append(instructions)
304+305+@@ -624,36 +623,19 @@ class Form(object):
306+ return key in self.fields
307+308+309+- def iterkeys(self):
310++ def keys(self):
311+ return iter(self)
312+313+314+- def itervalues(self):
315++ def values(self):
316+ for key in self:
317+ yield self[key]
318+319+320+- def iteritems(self):
321++ def items(self):
322+ for key in self:
323+ yield (key, self[key])
324+325+- if _PY3:
326+- keys = iterkeys
327+- values = itervalues
328+- items = iteritems
329+- else:
330+- def keys(self):
331+- return list(self)
332+-
333+-
334+- def values(self):
335+- return list(self.itervalues())
336+-
337+-
338+- def items(self):
339+- return list(self.iteritems())
340+-
341+-
342+ def getValues(self):
343+ """
344+ Extract values from the named form fields.
345+@@ -701,7 +683,7 @@ class Form(object):
346+347+ filtered = []
348+349+- for name, field in iteritems(self.fields):
350++ for name, field in self.fields.items():
351+ if name in fieldDefs:
352+ fieldDef = fieldDefs[name]
353+ if 'type' not in fieldDef:
354+diff --git a/wokkel/delay.py b/wokkel/delay.py
355+index be06cb3..1dd1703 100644
356+--- a/wokkel/delay.py
357++++ b/wokkel/delay.py
358+@@ -46,7 +46,7 @@ class Delay(object):
359+ Render this instance into a domish Element.
360+361+ @param legacy: If C{True}, use the legacy XEP-0091 format.
362+- @type legacy: C{bool}
363++ @type legacy: L{bool}
364+ """
365+ if not self.stamp:
366+ raise ValueError("stamp is required")
367+diff --git a/wokkel/disco.py b/wokkel/disco.py
368+index 9ea43ef..227789d 100644
369+--- a/wokkel/disco.py
370++++ b/wokkel/disco.py
371+@@ -13,7 +13,6 @@ U{XEP-0030<http://xmpp.org/extensions/xep-0030.html>}.
372+ from __future__ import division, absolute_import
373+374+ from twisted.internet import defer
375+-from twisted.python.compat import iteritems, unicode
376+ from twisted.words.protocols.jabber import error, jid
377+ from twisted.words.xish import domish
378+379+@@ -29,11 +28,11 @@ IQ_GET = '/iq[@type="get"]'
380+ DISCO_INFO = IQ_GET + '/query[@xmlns="' + NS_DISCO_INFO + '"]'
381+ DISCO_ITEMS = IQ_GET + '/query[@xmlns="' + NS_DISCO_ITEMS + '"]'
382+383+-class DiscoFeature(unicode):
384++class DiscoFeature(str):
385+ """
386+ XMPP service discovery feature.
387+388+- This extends C{unicode} to convert to and from L{domish.Element}, but
389++ This extends L{str} to convert to and from L{domish.Element}, but
390+ further behaves identically.
391+ """
392+393+@@ -44,7 +43,7 @@ class DiscoFeature(unicode):
394+ @rtype: L{domish.Element}.
395+ """
396+ element = domish.Element((NS_DISCO_INFO, 'feature'))
397+- element['var'] = unicode(self)
398++ element['var'] = str(self)
399+ return element
400+401+402+@@ -68,11 +67,11 @@ class DiscoIdentity(object):
403+ XMPP service discovery identity.
404+405+ @ivar category: The identity category.
406+- @type category: C{unicode}
407++ @type category: L{str}
408+ @ivar type: The identity type.
409+- @type type: C{unicode}
410++ @type type: L{str}
411+ @ivar name: The optional natural language name for this entity.
412+- @type name: C{unicode}
413++ @type name: L{str}
414+ """
415+416+ def __init__(self, category, idType, name=None):
417+@@ -119,21 +118,21 @@ class DiscoInfo(object):
418+ XMPP service discovery info.
419+420+ @ivar nodeIdentifier: The optional node this info applies to.
421+- @type nodeIdentifier: C{unicode}
422++ @type nodeIdentifier: L{str}
423+ @ivar features: Features as L{DiscoFeature}.
424+- @type features: C{set}
425++ @type features: L{set}
426+ @ivar identities: Identities as a mapping from (category, type) to name,
427+- all C{unicode}.
428+- @type identities: C{dict}
429++ all L{str}.
430++ @type identities: L{dict}
431+ @ivar extensions: Service discovery extensions as a mapping from the
432+- extension form's C{FORM_TYPE} (C{unicode}) to
433++ extension form's C{FORM_TYPE} (L{str}) to
434+ L{data_form.Form}. Forms with no C{FORM_TYPE} field
435+ are mapped as C{None}. Note that multiple forms
436+ with the same C{FORM_TYPE} have the last in sequence
437+ prevail.
438+- @type extensions: C{dict}
439++ @type extensions: L{dict}
440+ @ivar _items: Sequence of added items.
441+- @type _items: C{list}
442++ @type _items: L{list}
443+ """
444+445+ def __init__(self):
446+@@ -226,9 +225,9 @@ class DiscoItem(object):
447+ @ivar entity: The entity holding the item.
448+ @type entity: L{jid.JID}
449+ @ivar nodeIdentifier: The optional node identifier for the item.
450+- @type nodeIdentifier: C{unicode}
451++ @type nodeIdentifier: L{str}
452+ @ivar name: The optional natural language name for this entity.
453+- @type name: C{unicode}
454++ @type name: L{str}
455+ """
456+457+ def __init__(self, entity, nodeIdentifier='', name=None):
458+@@ -278,9 +277,9 @@ class DiscoItems(object):
459+ XMPP service discovery items.
460+461+ @ivar nodeIdentifier: The optional node this info applies to.
462+- @type nodeIdentifier: C{unicode}
463++ @type nodeIdentifier: L{str}
464+ @ivar _items: Sequence of added items.
465+- @type _items: C{list}
466++ @type _items: L{list}
467+ """
468+469+ def __init__(self):
470+@@ -353,9 +352,9 @@ class _DiscoRequest(generic.Request):
471+ A Service Discovery request.
472+473+ @ivar verb: Type of request: C{'info'} or C{'items'}.
474+- @type verb: C{str}
475++ @type verb: L{str}
476+ @ivar nodeIdentifier: Optional node to request info for.
477+- @type nodeIdentifier: C{unicode}
478++ @type nodeIdentifier: L{str}
479+ """
480+481+ verb = None
482+@@ -366,7 +365,7 @@ class _DiscoRequest(generic.Request):
483+ NS_DISCO_ITEMS: 'items',
484+ }
485+486+- _verbRequestMap = dict(((v, k) for k, v in iteritems(_requestVerbMap)))
487++ _verbRequestMap = dict(((v, k) for k, v in _requestVerbMap.items()))
488+489+ def __init__(self, verb=None, nodeIdentifier='',
490+ recipient=None, sender=None):
491+@@ -415,7 +414,7 @@ class DiscoClientProtocol(XMPPHandler):
492+ @type entity: L{jid.JID}
493+494+ @param nodeIdentifier: Optional node to request info from.
495+- @type nodeIdentifier: C{unicode}
496++ @type nodeIdentifier: L{str}
497+498+ @param sender: Optional sender address.
499+ @type sender: L{jid.JID}
500+@@ -438,7 +437,7 @@ class DiscoClientProtocol(XMPPHandler):
501+ @type entity: L{jid.JID}
502+503+ @param nodeIdentifier: Optional node to request info from.
504+- @type nodeIdentifier: C{unicode}
505++ @type nodeIdentifier: L{str}
506+507+ @param sender: Optional sender address.
508+ @type sender: L{jid.JID}
509+@@ -534,7 +533,7 @@ class DiscoHandler(XMPPHandler, IQHandlerMixin):
510+511+ @param deferredList: List of deferreds for which the results should be
512+ gathered.
513+- @type deferredList: C{list}
514++ @type deferredList: L{list}
515+ @return: Deferred that fires with a list of gathered results.
516+ @rtype: L{defer.Deferred}
517+ """
518+@@ -566,7 +565,7 @@ class DiscoHandler(XMPPHandler, IQHandlerMixin):
519+ @param target: The entity the request was sent to.
520+ @type target: L{JID<twisted.words.protocols.jabber.jid.JID>}
521+ @param nodeIdentifier: The optional node being queried, or C{''}.
522+- @type nodeIdentifier: C{unicode}
523++ @type nodeIdentifier: L{str}
524+ @return: Deferred with the gathered results from sibling handlers.
525+ @rtype: L{defer.Deferred}
526+ """
527+@@ -589,7 +588,7 @@ class DiscoHandler(XMPPHandler, IQHandlerMixin):
528+ @param target: The entity the request was sent to.
529+ @type target: L{JID<twisted.words.protocols.jabber.jid.JID>}
530+ @param nodeIdentifier: The optional node being queried, or C{''}.
531+- @type nodeIdentifier: C{unicode}
532++ @type nodeIdentifier: L{str}
533+ @return: Deferred with the gathered results from sibling handlers.
534+ @rtype: L{defer.Deferred}
535+ """
536+diff --git a/wokkel/formats.py b/wokkel/formats.py
537+index 0eb0be6..972cc7e 100644
538+--- a/wokkel/formats.py
539++++ b/wokkel/formats.py
540+@@ -9,8 +9,6 @@ Generic payload formats.
541+542+ from __future__ import division, absolute_import
543+544+-from twisted.python.compat import unicode
545+-
546+ NS_MOOD = 'http://jabber.org/protocol/mood'
547+ NS_TUNE = 'http://jabber.org/protocol/tune'
548+549+@@ -55,7 +53,7 @@ class Mood:
550+ continue
551+552+ if child.name == 'text':
553+- text = unicode(child)
554++ text = str(child)
555+ else:
556+ value = child.name
557+558+@@ -76,19 +74,19 @@ class Tune:
559+ U{XEP-0118<http://xmpp.org/extensions/xep-0118.html>}.
560+561+ @ivar artist: The artist or performer of the song or piece.
562+- @type artist: C{unicode}
563++ @type artist: L{str}
564+ @ivar length: The duration of the song or piece in seconds.
565+- @type length: C{int}
566++ @type length: L{int}
567+ @ivar source: The collection (e.g. album) or other source.
568+- @type source: C{unicode}
569++ @type source: L{str}
570+ @ivar title: The title of the song or piece
571+- @type title: C{unicode}
572++ @type title: L{str}
573+ @ivar track: A unique identifier for the tune; e.g. the track number within
574+ the collection or the specific URI for the object.
575+- @type track: C{unicode}
576++ @type track: L{str}
577+ @ivar uri: A URI pointing to information about the song, collection, or
578+ artist.
579+- @type uri: C{str}
580++ @type uri: L{str}
581+582+ """
583+584+@@ -122,10 +120,10 @@ class Tune:
585+ continue
586+587+ if child.name in ('artist', 'source', 'title', 'track', 'uri'):
588+- setattr(tune, child.name, unicode(child))
589++ setattr(tune, child.name, str(child))
590+ elif child.name == 'length':
591+ try:
592+- tune.length = int(unicode(child))
593++ tune.length = int(str(child))
594+ except ValueError:
595+ pass
596+597+diff --git a/wokkel/generic.py b/wokkel/generic.py
598+index 2e975f6..becff8f 100644
599+--- a/wokkel/generic.py
600++++ b/wokkel/generic.py
601+@@ -13,14 +13,11 @@ from zope.interface import implementer
602+603+ from twisted.internet import defer, protocol
604+ from twisted.python import reflect
605+-from twisted.python.deprecate import deprecated
606+ from twisted.words.protocols.jabber import error, jid, xmlstream
607+ from twisted.words.protocols.jabber.xmlstream import toResponse
608+ from twisted.words.xish import domish, utility
609+ from twisted.words.xish.xmlstream import BootstrapMixin
610+611+-from incremental import Version
612+-
613+ from wokkel.iwokkel import IDisco
614+ from wokkel.subprotocols import XMPPHandler
615+616+@@ -35,7 +32,7 @@ def parseXml(string):
617+ Parse serialized XML into a DOM structure.
618+619+ @param string: The serialized XML to be parsed, UTF-8 encoded.
620+- @type string: C{str}.
621++ @type string: L{str}.
622+ @return: The DOM structure, or C{None} on empty or incomplete input.
623+ @rtype: L{domish.Element}
624+ """
625+@@ -332,17 +329,3 @@ class DeferredXmlStreamFactory(BootstrapMixin, protocol.ClientFactory):
626+627+ def clientConnectionFailed(self, connector, reason):
628+ self.deferred.errback(reason)
629+-
630+-
631+-
632+-@deprecated(Version("wokkel", 18, 0, 0), "unicode.encode('idna')")
633+-def prepareIDNName(name):
634+- """
635+- Encode a unicode IDN Domain Name into its ACE equivalent.
636+-
637+- This will encode the domain labels, separated by allowed dot code points,
638+- to their ASCII Compatible Encoding (ACE) equivalent, using punycode. The
639+- result is an ASCII byte string of the encoded labels, separated by the
640+- standard full stop.
641+- """
642+- return name.encode('idna')
643+diff --git a/wokkel/iwokkel.py b/wokkel/iwokkel.py
644+index 30a1057..35383b5 100644
645+--- a/wokkel/iwokkel.py
646++++ b/wokkel/iwokkel.py
647+@@ -46,7 +46,7 @@ class IDisco(Interface):
648+ @param nodeIdentifier: The optional identifier of the node at this
649+ entity to retrieve the identify and features of. The default is
650+ C{''}, meaning the root node.
651+- @type nodeIdentifier: C{unicode}
652++ @type nodeIdentifier: L{str}
653+ """
654+655+ def getDiscoItems(requestor, target, nodeIdentifier=''):
656+@@ -60,7 +60,7 @@ class IDisco(Interface):
657+ @param nodeIdentifier: The optional identifier of the node at this
658+ entity to retrieve the identify and features of.
659+ The default is C{''}, meaning the root node.
660+- @type nodeIdentifier: C{unicode}
661++ @type nodeIdentifier: L{str}
662+ """
663+664+665+@@ -109,7 +109,7 @@ class IPubSubClient(Interface):
666+ @param nodeIdentifier: Optional suggestion for the new node's
667+ identifier. If omitted, the creation of an
668+ instant node will be attempted.
669+- @type nodeIdentifier: C{unicode}
670++ @type nodeIdentifier: L{str}
671+ @return: a deferred that fires with the identifier of the newly created
672+ node. Note that this can differ from the suggested identifier
673+ if the publish subscribe service chooses to modify or ignore
674+@@ -124,7 +124,7 @@ class IPubSubClient(Interface):
675+ @param service: The publish-subscribe service entity.
676+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
677+ @param nodeIdentifier: Identifier of the node to be deleted.
678+- @type nodeIdentifier: C{unicode}
679++ @type nodeIdentifier: L{str}
680+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
681+ """
682+683+@@ -135,7 +135,7 @@ class IPubSubClient(Interface):
684+ @param service: The publish-subscribe service entity.
685+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
686+ @param nodeIdentifier: Identifier of the node to subscribe to.
687+- @type nodeIdentifier: C{unicode}
688++ @type nodeIdentifier: L{str}
689+ @param subscriber: JID to subscribe to the node.
690+ @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
691+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
692+@@ -148,7 +148,7 @@ class IPubSubClient(Interface):
693+ @param service: The publish-subscribe service entity.
694+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
695+ @param nodeIdentifier: Identifier of the node to unsubscribe from.
696+- @type nodeIdentifier: C{unicode}
697++ @type nodeIdentifier: L{str}
698+ @param subscriber: JID to unsubscribe from the node.
699+ @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
700+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
701+@@ -165,9 +165,9 @@ class IPubSubClient(Interface):
702+ @param service: The publish-subscribe service entity.
703+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
704+ @param nodeIdentifier: Identifier of the node to publish to.
705+- @type nodeIdentifier: C{unicode}
706++ @type nodeIdentifier: L{str}
707+ @param items: List of item elements.
708+- @type items: C{list} of L{Item}
709++ @type items: L{list} of L{Item}
710+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
711+ """
712+713+@@ -191,12 +191,12 @@ class IPubSubService(Interface):
714+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
715+ @param nodeIdentifier: The identifier of the node that was published
716+ to.
717+- @type nodeIdentifier: C{unicode}
718++ @type nodeIdentifier: L{str}
719+ @param notifications: The notifications as tuples of subscriber, the
720+ list of subscriptions and the list of items to be notified.
721+- @type notifications: C{list} of
722+- (L{JID<twisted.words.protocols.jabber.jid.JID>}, C{list} of
723+- L{Subscription<wokkel.pubsub.Subscription>}, C{list} of
724++ @type notifications: L{list} of
725++ (L{JID<twisted.words.protocols.jabber.jid.JID>}, L{list} of
726++ L{Subscription<wokkel.pubsub.Subscription>}, L{list} of
727+ L{Element<twisted.words.xish.domish.Element>})
728+ """
729+730+@@ -209,14 +209,14 @@ class IPubSubService(Interface):
731+ @param service: The entity the notifications will originate from.
732+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
733+ @param nodeIdentifier: The identifier of the node that was deleted.
734+- @type nodeIdentifier: C{unicode}
735++ @type nodeIdentifier: L{str}
736+ @param subscribers: The subscribers for which a notification should be
737+ sent out.
738+- @type subscribers: C{list} of
739++ @type subscribers: L{list} of
740+ L{JID<twisted.words.protocols.jabber.jid.JID>}
741+ @param redirectURI: Optional XMPP URI of another node that subscribers
742+ are redirected to.
743+- @type redirectURI: C{str}
744++ @type redirectURI: L{str}
745+ """
746+747+ def publish(requestor, service, nodeIdentifier, items):
748+@@ -228,9 +228,9 @@ class IPubSubService(Interface):
749+ @param service: The entity the request was addressed to.
750+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
751+ @param nodeIdentifier: The identifier of the node to publish to.
752+- @type nodeIdentifier: C{unicode}
753++ @type nodeIdentifier: L{str}
754+ @param items: The items to be published as elements.
755+- @type items: C{list} of C{Element<twisted.words.xish.domish.Element>}
756++ @type items: L{list} of C{Element<twisted.words.xish.domish.Element>}
757+ @return: deferred that fires on success.
758+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
759+ """
760+@@ -244,7 +244,7 @@ class IPubSubService(Interface):
761+ @param service: The entity the request was addressed to.
762+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
763+ @param nodeIdentifier: The identifier of the node to subscribe to.
764+- @type nodeIdentifier: C{unicode}
765++ @type nodeIdentifier: L{str}
766+ @param subscriber: The entity to be subscribed.
767+ @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
768+ @return: A deferred that fires with a
769+@@ -261,7 +261,7 @@ class IPubSubService(Interface):
770+ @param service: The entity the request was addressed to.
771+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
772+ @param nodeIdentifier: The identifier of the node to unsubscribe from.
773+- @type nodeIdentifier: C{unicode}
774++ @type nodeIdentifier: L{str}
775+ @param subscriber: The entity to be unsubscribed.
776+ @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
777+ @return: A deferred that fires with C{None} when unsubscription has
778+@@ -277,7 +277,7 @@ class IPubSubService(Interface):
779+ @type requestor: L{JID<twisted.words.protocols.jabber.jid.JID>}
780+ @param service: The entity the request was addressed to.
781+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
782+- @return: A deferred that fires with a C{list} of subscriptions as
783++ @return: A deferred that fires with a L{list} of subscriptions as
784+ L{Subscription<wokkel.pubsub.Subscription>}.
785+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
786+ """
787+@@ -290,9 +290,9 @@ class IPubSubService(Interface):
788+ @type requestor: L{JID<twisted.words.protocols.jabber.jid.JID>}
789+ @param service: The entity the request was addressed to.
790+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
791+- @return: A deferred that fires with a C{list} of affiliations as
792+- C{tuple}s of (node identifier as C{unicode}, affiliation state as
793+- C{str}). The affiliation can be C{'owner'}, C{'publisher'}, or
794++ @return: A deferred that fires with a L{list} of affiliations as
795++ C{tuple}s of (node identifier as L{str}, affiliation state as
796++ L{str}). The affiliation can be C{'owner'}, C{'publisher'}, or
797+ C{'outcast'}.
798+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
799+ """
800+@@ -308,8 +308,8 @@ class IPubSubService(Interface):
801+ @param nodeIdentifier: The suggestion for the identifier of the node
802+ to be created. If the request did not include a suggestion for the
803+ node identifier, the value is C{None}.
804+- @type nodeIdentifier: C{unicode} or C{NoneType}
805+- @return: A deferred that fires with a C{unicode} that represents
806++ @type nodeIdentifier: L{str} or C{NoneType}
807++ @return: A deferred that fires with a L{str} that represents
808+ the identifier of the new node.
809+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
810+ """
811+@@ -322,10 +322,10 @@ class IPubSubService(Interface):
812+ by option name. The value of each entry represents the specifics for
813+ that option in a dictionary:
814+815+- - C{'type'} (C{str}): The option's type (see
816++ - C{'type'} (L{str}): The option's type (see
817+ L{Field<wokkel.data_form.Field>}'s doc string for possible values).
818+- - C{'label'} (C{unicode}): A human readable label for this option.
819+- - C{'options'} (C{dict}): Optional list of possible values for this
820++ - C{'label'} (L{str}): A human readable label for this option.
821++ - C{'options'} (L{dict}): Optional list of possible values for this
822+ option.
823+824+ Example::
825+@@ -346,7 +346,7 @@ class IPubSubService(Interface):
826+ }
827+ }
828+829+- @rtype: C{dict}.
830++ @rtype: L{dict}.
831+ """
832+833+ def getDefaultConfiguration(requestor, service, nodeType):
834+@@ -359,11 +359,11 @@ class IPubSubService(Interface):
835+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
836+ @param nodeType: The type of node for which the configuration is
837+ retrieved, C{'leaf'} or C{'collection'}.
838+- @type nodeType: C{str}
839+- @return: A deferred that fires with a C{dict} representing the default
840+- node configuration. Keys are C{str}s that represent the
841+- field name. Values can be of types C{unicode}, C{int} or
842+- C{bool}.
843++ @type nodeType: L{str}
844++ @return: A deferred that fires with a L{dict} representing the default
845++ node configuration. Keys are L{str}s that represent the
846++ field name. Values can be of types L{str}, L{int} or
847++ L{bool}.
848+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
849+ """
850+851+@@ -377,10 +377,10 @@ class IPubSubService(Interface):
852+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
853+ @param nodeIdentifier: The identifier of the node to retrieve the
854+ configuration from.
855+- @type nodeIdentifier: C{unicode}
856+- @return: A deferred that fires with a C{dict} representing the node
857+- configuration. Keys are C{str}s that represent the field name.
858+- Values can be of types C{unicode}, C{int} or C{bool}.
859++ @type nodeIdentifier: L{str}
860++ @return: A deferred that fires with a L{dict} representing the node
861++ configuration. Keys are L{str}s that represent the field name.
862++ Values can be of types L{str}, L{int} or L{bool}.
863+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
864+ """
865+866+@@ -394,7 +394,7 @@ class IPubSubService(Interface):
867+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
868+ @param nodeIdentifier: The identifier of the node to change the
869+ configuration of.
870+- @type nodeIdentifier: C{unicode}
871++ @type nodeIdentifier: L{str}
872+ @return: A deferred that fires with C{None} when the node's
873+ configuration has been changed.
874+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
875+@@ -410,7 +410,7 @@ class IPubSubService(Interface):
876+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
877+ @param nodeIdentifier: The identifier of the node to retrieve items
878+ from.
879+- @type nodeIdentifier: C{unicode}
880++ @type nodeIdentifier: L{str}
881+ """
882+883+ def retract(requestor, service, nodeIdentifier, itemIdentifiers):
884+@@ -423,7 +423,7 @@ class IPubSubService(Interface):
885+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
886+ @param nodeIdentifier: The identifier of the node to retract items
887+ from.
888+- @type nodeIdentifier: C{unicode}
889++ @type nodeIdentifier: L{str}
890+ """
891+892+ def purge(requestor, service, nodeIdentifier):
893+@@ -435,7 +435,7 @@ class IPubSubService(Interface):
894+ @param service: The entity the request was addressed to.
895+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
896+ @param nodeIdentifier: The identifier of the node to be purged.
897+- @type nodeIdentifier: C{unicode}
898++ @type nodeIdentifier: L{str}
899+ """
900+901+ def delete(requestor, service, nodeIdentifier):
902+@@ -447,7 +447,7 @@ class IPubSubService(Interface):
903+ @param service: The entity the request was addressed to.
904+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
905+ @param nodeIdentifier: The identifier of the node to be delete.
906+- @type nodeIdentifier: C{unicode}
907++ @type nodeIdentifier: L{str}
908+ """
909+910+911+@@ -472,7 +472,7 @@ class IPubSubResource(Interface):
912+ @param service: The publish-subscribe service entity.
913+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
914+ @param nodeIdentifier: Identifier of the node to request the info for.
915+- @type nodeIdentifier: C{unicode}
916++ @type nodeIdentifier: L{str}
917+ @return: A deferred that fires with a dictionary. If not empty,
918+ it must have the keys C{'type'} and C{'meta-data'} to keep
919+ respectively the node type and a dictionary with the meta
920+@@ -491,7 +491,7 @@ class IPubSubResource(Interface):
921+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
922+ @param nodeIdentifier: Identifier of the node to request the childs
923+ for.
924+- @type nodeIdentifier: C{unicode}
925++ @type nodeIdentifier: L{str}
926+ @return: A deferred that fires with a list of child node identifiers.
927+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
928+ """
929+@@ -505,10 +505,10 @@ class IPubSubResource(Interface):
930+ by option name. The value of each entry represents the specifics for
931+ that option in a dictionary:
932+933+- - C{'type'} (C{str}): The option's type (see
934++ - C{'type'} (L{str}): The option's type (see
935+ L{Field<wokkel.data_form.Field>}'s doc string for possible values).
936+- - C{'label'} (C{unicode}): A human readable label for this option.
937+- - C{'options'} (C{dict}): Optional list of possible values for this
938++ - C{'label'} (L{str}): A human readable label for this option.
939++ - C{'options'} (L{dict}): Optional list of possible values for this
940+ option.
941+942+ Example::
943+@@ -529,7 +529,7 @@ class IPubSubResource(Interface):
944+ }
945+ }
946+947+- @rtype: C{dict}.
948++ @rtype: L{dict}.
949+ """
950+951+952+@@ -574,7 +574,7 @@ class IPubSubResource(Interface):
953+954+ @param request: The publish-subscribe request.
955+ @type request: L{wokkel.pubsub.PubSubRequest}
956+- @return: A deferred that fires with a C{list} of subscriptions as
957++ @return: A deferred that fires with a L{list} of subscriptions as
958+ L{Subscription<wokkel.pubsub.Subscription>}.
959+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
960+ """
961+@@ -586,9 +586,9 @@ class IPubSubResource(Interface):
962+963+ @param request: The publish-subscribe request.
964+ @type request: L{wokkel.pubsub.PubSubRequest}
965+- @return: A deferred that fires with a C{list} of affiliations as
966+- C{tuple}s of (node identifier as C{unicode}, affiliation state as
967+- C{str}). The affiliation can be C{'owner'}, C{'publisher'}, or
968++ @return: A deferred that fires with a L{list} of affiliations as
969++ C{tuple}s of (node identifier as L{str}, affiliation state as
970++ L{str}). The affiliation can be C{'owner'}, C{'publisher'}, or
971+ C{'outcast'}.
972+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
973+ """
974+@@ -600,7 +600,7 @@ class IPubSubResource(Interface):
975+976+ @param request: The publish-subscribe request.
977+ @type request: L{wokkel.pubsub.PubSubRequest}
978+- @return: A deferred that fires with a C{unicode} that represents
979++ @return: A deferred that fires with a L{str} that represents
980+ the identifier of the new node.
981+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
982+ """
983+@@ -612,10 +612,10 @@ class IPubSubResource(Interface):
984+985+ @param request: The publish-subscribe request.
986+ @type request: L{wokkel.pubsub.PubSubRequest}
987+- @return: A deferred that fires with a C{dict} representing the default
988+- node configuration. Keys are C{str}s that represent the
989+- field name. Values can be of types C{unicode}, C{int} or
990+- C{bool}.
991++ @return: A deferred that fires with a L{dict} representing the default
992++ node configuration. Keys are L{str}s that represent the
993++ field name. Values can be of types L{str}, L{int} or
994++ L{bool}.
995+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
996+ """
997+998+@@ -626,9 +626,9 @@ class IPubSubResource(Interface):
999+1000+ @param request: The publish-subscribe request.
1001+ @type request: L{wokkel.pubsub.PubSubRequest}
1002+- @return: A deferred that fires with a C{dict} representing the node
1003+- configuration. Keys are C{str}s that represent the field name.
1004+- Values can be of types C{unicode}, C{int} or C{bool}.
1005++ @return: A deferred that fires with a L{dict} representing the node
1006++ configuration. Keys are L{str}s that represent the field name.
1007++ Values can be of types L{str}, L{int} or L{bool}.
1008+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
1009+ """
1010+1011+@@ -651,7 +651,7 @@ class IPubSubResource(Interface):
1012+1013+ @param request: The publish-subscribe request.
1014+ @type request: L{wokkel.pubsub.PubSubRequest}
1015+- @return: A deferred that fires with a C{list} of L{pubsub.Item}.
1016++ @return: A deferred that fires with a L{list} of L{pubsub.Item}.
1017+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
1018+ """
1019+1020+@@ -698,9 +698,9 @@ class IPubSubResource(Interface):
1021+1022+ @param request: The publish-subscribe request.
1023+ @type request: L{wokkel.pubsub.PubSubRequest}
1024+- @return: A deferred that fires with a C{dict} of affiliations with the
1025++ @return: A deferred that fires with a L{dict} of affiliations with the
1026+ entity as key (L{JID<twisted.words.protocols.jabber.jid.JID>}) and
1027+- the affiliation state as value (C{unicode}). The affiliation can
1028++ the affiliation state as value (L{str}). The affiliation can
1029+ be C{u'owner'}, C{u'publisher'}, or C{u'outcast'}.
1030+ @rtype: L{Deferred<twisted.internet.defer.Deferred>}
1031+1032+@@ -748,7 +748,7 @@ class IMUCClient(Interface):
1033+ @type user: L{muc.User}
1034+1035+ @param subject: The subject of the given room.
1036+- @type subject: C{unicode}
1037++ @type subject: L{str}
1038+ """
1039+1040+1041+@@ -769,7 +769,7 @@ class IMUCClient(Interface):
1042+1043+ @param options: A mapping of field names to values, or C{None} to
1044+ cancel.
1045+- @type options: C{dict}
1046++ @type options: L{dict}
1047+ """
1048+1049+1050+@@ -796,14 +796,14 @@ class IMUCClient(Interface):
1051+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
1052+1053+ @param nick: The nick name for the entitity joining the room.
1054+- @type nick: C{unicode}
1055++ @type nick: L{str}
1056+1057+ @param historyOptions: Options for conversation history sent by the
1058+ room upon joining.
1059+ @type historyOptions: L{HistoryOptions}
1060+1061+ @param password: Optional password for the room.
1062+- @type password: C{unicode}
1063++ @type password: L{str}
1064+1065+ @return: A deferred that fires when the entity is in the room or an
1066+ error has occurred.
1067+@@ -820,7 +820,7 @@ class IMUCClient(Interface):
1068+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
1069+1070+ @param nick: The new nick name within the room.
1071+- @type nick: C{unicode}
1072++ @type nick: L{str}
1073+ """
1074+1075+1076+@@ -876,7 +876,7 @@ class IMUCClient(Interface):
1077+1078+ @param options: A mapping of field names to values, or C{None} to
1079+ cancel.
1080+- @type options: C{dict}
1081++ @type options: L{dict}
1082+ """
1083+1084+1085+@@ -890,7 +890,7 @@ class IMUCClient(Interface):
1086+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
1087+1088+ @param subject: The subject you want to set.
1089+- @type subject: C{unicode}
1090++ @type subject: L{str}
1091+ """
1092+1093+1094+@@ -917,7 +917,7 @@ class IMUCClient(Interface):
1095+ holding the original stanza a
1096+ L{Element<twisted.words.xish.domish.Element>}, and C{'timestamp'}
1097+ with the timestamp.
1098+- @type messages: C{list} of
1099++ @type messages: L{list} of
1100+ L{Element<twisted.words.xish.domish.Element>}
1101+ """
1102+1103+@@ -933,7 +933,7 @@ class IMUCClient(Interface):
1104+ @type entity: L{JID<twisted.words.protocols.jabber.jid.JID>}
1105+1106+ @param reason: The reason for banning the entity.
1107+- @type reason: C{unicode}
1108++ @type reason: L{str}
1109+1110+ @param sender: The entity sending the request.
1111+ @type sender: L{JID<twisted.words.protocols.jabber.jid.JID>}
1112+@@ -949,10 +949,10 @@ class IMUCClient(Interface):
1113+1114+ @param nick: The occupant to be banned.
1115+ @type nick: L{JID<twisted.words.protocols.jabber.jid.JID>} or
1116+- C{unicode}
1117++ L{str}
1118+1119+ @param reason: The reason given for the kick.
1120+- @type reason: C{unicode}
1121++ @type reason: L{str}
1122+1123+ @param sender: The entity sending the request.
1124+ @type sender: L{JID<twisted.words.protocols.jabber.jid.JID>}
1125+diff --git a/wokkel/muc.py b/wokkel/muc.py
1126+index 330664b..4c826f2 100644
1127+--- a/wokkel/muc.py
1128++++ b/wokkel/muc.py
1129+@@ -17,7 +17,6 @@ from dateutil.tz import tzutc
1130+ from zope.interface import implementer
1131+1132+ from twisted.internet import defer
1133+-from twisted.python.compat import unicode
1134+ from twisted.python.constants import Values, ValueConstant
1135+ from twisted.words.protocols.jabber import jid, error, xmlstream
1136+ from twisted.words.xish import domish
1137+@@ -192,7 +191,7 @@ class AdminItem(object):
1138+ item.role = element.getAttribute('role')
1139+1140+ for child in element.elements(NS_MUC_ADMIN, 'reason'):
1141+- item.reason = unicode(child)
1142++ item.reason = str(child)
1143+1144+ return item
1145+1146+@@ -228,13 +227,13 @@ class DestructionRequest(generic.Request):
1147+ Room destruction request.
1148+1149+ @param reason: Optional reason for the destruction of this room.
1150+- @type reason: L{unicode}.
1151++ @type reason: L{str}.
1152+1153+ @param alternate: Optional room JID of an alternate venue.
1154+ @type alternate: L{JID<twisted.words.protocols.jabber.jid.JID>}
1155+1156+ @param password: Optional password for entering the alternate venue.
1157+- @type password: L{unicode}
1158++ @type password: L{str}
1159+ """
1160+1161+ stanzaType = 'set'
1162+@@ -395,10 +394,10 @@ class UserPresence(xmppim.AvailabilityPresence):
1163+ Availability presence sent from MUC service to client.
1164+1165+ @ivar affiliation: Affiliation of the entity to the room.
1166+- @type affiliation: L{unicode}
1167++ @type affiliation: L{str}
1168+1169+ @ivar role: Role of the entity in the room.
1170+- @type role: L{unicode}
1171++ @type role: L{str}
1172+1173+ @ivar entity: The real JID of the entity this presence is from.
1174+ @type entity: L{JID<twisted.words.protocols.jabber.jid.JID>}
1175+@@ -408,7 +407,7 @@ class UserPresence(xmppim.AvailabilityPresence):
1176+ @type mucStatuses: L{Statuses}
1177+1178+ @ivar nick: The nick name of the entity in the room.
1179+- @type nick: L{unicode}
1180++ @type nick: L{str}
1181+ """
1182+1183+ affiliation = None
1184+@@ -451,7 +450,7 @@ class UserPresence(xmppim.AvailabilityPresence):
1185+ self.role = child.getAttribute('role')
1186+1187+ for reason in child.elements(NS_MUC_ADMIN, 'reason'):
1188+- self.reason = unicode(reason)
1189++ self.reason = str(reason)
1190+1191+ # TODO: destroy
1192+1193+@@ -595,14 +594,14 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
1194+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
1195+1196+ @param nick: The nick name for the entitity joining the room.
1197+- @type nick: L{unicode}
1198++ @type nick: L{str}
1199+1200+ @param historyOptions: Options for conversation history sent by the
1201+ room upon joining.
1202+ @type historyOptions: L{HistoryOptions}
1203+1204+ @param password: Optional password for the room.
1205+- @type password: L{unicode}
1206++ @type password: L{str}
1207+1208+ @return: A deferred that fires when the entity is in the room or an
1209+ error has occurred.
1210+@@ -628,7 +627,7 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
1211+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
1212+1213+ @param nick: The new nick name within the room.
1214+- @type nick: L{unicode}
1215++ @type nick: L{str}
1216+ """
1217+ occupantJID = jid.JID(tuple=(roomJID.user, roomJID.host, nick))
1218+ presence = BasicPresence(recipient=occupantJID)
1219+@@ -646,10 +645,10 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
1220+1221+ @param show: The availability of the entity. Common values are xa,
1222+ available, etc
1223+- @type show: L{unicode}
1224++ @type show: L{str}
1225+1226+ @param status: The current status of the entity.
1227+- @type status: L{unicode}
1228++ @type status: L{str}
1229+ """
1230+ occupantJID = self._roomOccupantMap[roomJID]
1231+ presence = BasicPresence(recipient=occupantJID, show=show,
1232+@@ -704,7 +703,7 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
1233+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
1234+1235+ @param subject: The subject you want to set.
1236+- @type subject: L{unicode}
1237++ @type subject: L{str}
1238+ """
1239+ message = GroupChat(roomJID.userhostJID(), subject=subject)
1240+ self.send(message.toElement())
1241+@@ -723,7 +722,7 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
1242+ @type invitee: L{JID<twisted.words.protocols.jabber.jid.JID>}
1243+1244+ @param reason: The reason for the invite.
1245+- @type reason: L{unicode}
1246++ @type reason: L{str}
1247+ """
1248+ message = InviteMessage(recipient=roomJID, invitee=invitee,
1249+ reason=reason)
1250+@@ -970,7 +969,7 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
1251+ L{JID<twisted.words.protocols.jabber.jid.JID>}
1252+1253+ @param affiliation: The affilation to the entities will acquire.
1254+- @type affiliation: L{unicode}
1255++ @type affiliation: L{str}
1256+1257+ @param sender: The entity sending the request.
1258+ @type sender: L{JID<twisted.words.protocols.jabber.jid.JID>}
1259+@@ -992,10 +991,10 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
1260+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
1261+1262+ @param nick: The nick name for the user in this room.
1263+- @type nick: L{unicode}
1264++ @type nick: L{str}
1265+1266+ @param reason: The reason for granting voice to the entity.
1267+- @type reason: L{unicode}
1268++ @type reason: L{str}
1269+1270+ @param sender: The entity sending the request.
1271+ @type sender: L{JID<twisted.words.protocols.jabber.jid.JID>}
1272+@@ -1015,10 +1014,10 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
1273+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
1274+1275+ @param nick: The nick name for the user in this room.
1276+- @type nick: L{unicode}
1277++ @type nick: L{str}
1278+1279+ @param reason: The reason for revoking voice from the entity.
1280+- @type reason: L{unicode}
1281++ @type reason: L{str}
1282+1283+ @param sender: The entity sending the request.
1284+ @type sender: L{JID<twisted.words.protocols.jabber.jid.JID>}
1285+@@ -1035,10 +1034,10 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
1286+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
1287+1288+ @param nick: The nick name for the user in this room.
1289+- @type nick: L{unicode}
1290++ @type nick: L{str}
1291+1292+ @param reason: The reason for granting moderation to the entity.
1293+- @type reason: L{unicode}
1294++ @type reason: L{str}
1295+1296+ @param sender: The entity sending the request.
1297+ @type sender: L{JID<twisted.words.protocols.jabber.jid.JID>}
1298+@@ -1058,7 +1057,7 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
1299+ @type entity: L{JID<twisted.words.protocols.jabber.jid.JID>}
1300+1301+ @param reason: The reason for banning the entity.
1302+- @type reason: L{unicode}
1303++ @type reason: L{str}
1304+1305+ @param sender: The entity sending the request.
1306+ @type sender: L{JID<twisted.words.protocols.jabber.jid.JID>}
1307+@@ -1075,10 +1074,10 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
1308+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
1309+1310+ @param nick: The occupant to be banned.
1311+- @type nick: L{unicode}
1312++ @type nick: L{str}
1313+1314+ @param reason: The reason given for the kick.
1315+- @type reason: L{unicode}
1316++ @type reason: L{str}
1317+1318+ @param sender: The entity sending the request.
1319+ @type sender: L{JID<twisted.words.protocols.jabber.jid.JID>}
1320+@@ -1095,7 +1094,7 @@ class MUCClientProtocol(xmppim.BasePresenceProtocol):
1321+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
1322+1323+ @param reason: The reason for the destruction of the room.
1324+- @type reason: L{unicode}
1325++ @type reason: L{str}
1326+1327+ @param alternate: The JID of the room suggested as an alternate venue.
1328+ @type alternate: L{JID<twisted.words.protocols.jabber.jid.JID>}
1329+@@ -1135,7 +1134,7 @@ class Room(object):
1330+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
1331+1332+ @ivar nick: The nick name for the client in this room.
1333+- @type nick: L{unicode}
1334++ @type nick: L{str}
1335+1336+ @ivar occupantJID: The JID of the occupant in the room. Generated from
1337+ roomJID and nick.
1338+@@ -1190,7 +1189,7 @@ class Room(object):
1339+ Get a user from the room's roster.
1340+1341+ @param nick: The nick for the user in the MUC room.
1342+- @type nick: L{unicode}
1343++ @type nick: L{str}
1344+ """
1345+ return self.roster.get(nick)
1346+1347+@@ -1444,14 +1443,14 @@ class MUCClient(MUCClientProtocol):
1348+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
1349+1350+ @param nick: The nick name for the entitity joining the room.
1351+- @type nick: L{unicode}
1352++ @type nick: L{str}
1353+1354+ @param historyOptions: Options for conversation history sent by the
1355+ room upon joining.
1356+ @type historyOptions: L{HistoryOptions}
1357+1358+ @param password: Optional password for the room.
1359+- @type password: L{unicode}
1360++ @type password: L{str}
1361+1362+ @return: A deferred that fires with the room when the entity is in the
1363+ room, or with a failure if an error has occurred.
1364+@@ -1488,7 +1487,7 @@ class MUCClient(MUCClientProtocol):
1365+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
1366+1367+ @param nick: The new nick name within the room.
1368+- @type nick: L{unicode}
1369++ @type nick: L{str}
1370+ """
1371+ def cb(presence):
1372+ # Presence confirmation, change the nickname.
1373+@@ -1530,10 +1529,10 @@ class MUCClient(MUCClientProtocol):
1374+1375+ @param show: The availability of the entity. Common values are xa,
1376+ available, etc
1377+- @type show: L{unicode}
1378++ @type show: L{str}
1379+1380+ @param status: The current status of the entity.
1381+- @type status: L{unicode}
1382++ @type status: L{str}
1383+ """
1384+ room = self._getRoom(roomJID)
1385+ d = MUCClientProtocol.status(self, roomJID, show, status)
1386+@@ -1549,7 +1548,7 @@ class MUCClient(MUCClientProtocol):
1387+ @type roomJID: L{JID<twisted.words.protocols.jabber.jid.JID>}
1388+1389+ @param reason: The reason for the destruction of the room.
1390+- @type reason: L{unicode}
1391++ @type reason: L{str}
1392+1393+ @param alternate: The JID of the room suggested as an alternate venue.
1394+ @type alternate: L{JID<twisted.words.protocols.jabber.jid.JID>}
1395+diff --git a/wokkel/pubsub.py b/wokkel/pubsub.py
1396+index 689a6e2..2eb1b44 100644
1397+--- a/wokkel/pubsub.py
1398++++ b/wokkel/pubsub.py
1399+@@ -16,7 +16,6 @@ from zope.interface import implementer
1400+1401+ from twisted.internet import defer
1402+ from twisted.python import log
1403+-from twisted.python.compat import StringType, iteritems, unicode
1404+ from twisted.words.protocols.jabber import jid, error
1405+ from twisted.words.xish import domish
1406+1407+@@ -107,20 +106,20 @@ class Subscription(object):
1408+1409+ @ivar nodeIdentifier: The identifier of the node subscribed to. The root
1410+ node is denoted by L{None}.
1411+- @type nodeIdentifier: L{unicode}
1412++ @type nodeIdentifier: L{str}
1413+1414+ @ivar subscriber: The subscribing entity.
1415+ @type subscriber: L{jid.JID}
1416+1417+ @ivar state: The subscription state. One of C{'subscribed'}, C{'pending'},
1418+ C{'unconfigured'}.
1419+- @type state: L{unicode}
1420++ @type state: L{str}
1421+1422+ @ivar options: Optional list of subscription options.
1423+ @type options: L{dict}
1424+1425+ @ivar subscriptionIdentifier: Optional subscription identifier.
1426+- @type subscriptionIdentifier: L{unicode}
1427++ @type subscriptionIdentifier: L{str}
1428+ """
1429+1430+ def __init__(self, nodeIdentifier, subscriber, state, options=None,
1431+@@ -150,7 +149,7 @@ class Subscription(object):
1432+ element = domish.Element((defaultUri, 'subscription'))
1433+ if self.nodeIdentifier:
1434+ element['node'] = self.nodeIdentifier
1435+- element['jid'] = unicode(self.subscriber)
1436++ element['jid'] = str(self.subscriber)
1437+ element['subscription'] = self.state
1438+ if self.subscriptionIdentifier:
1439+ element['subid'] = self.subscriptionIdentifier
1440+@@ -171,17 +170,17 @@ class Item(domish.Element):
1441+ def __init__(self, id=None, payload=None):
1442+ """
1443+ @param id: optional item identifier
1444+- @type id: L{unicode}
1445++ @type id: L{str}
1446+ @param payload: optional item payload. Either as a domish element, or
1447+ as serialized XML.
1448+- @type payload: object providing L{domish.IElement} or L{unicode}.
1449++ @type payload: object providing L{domish.IElement} or L{str}.
1450+ """
1451+1452+ domish.Element.__init__(self, (None, 'item'))
1453+ if id is not None:
1454+ self['id'] = id
1455+ if payload is not None:
1456+- if isinstance(payload, StringType):
1457++ if isinstance(payload, str):
1458+ self.addRawXml(payload)
1459+ else:
1460+ self.addChild(payload)
1461+@@ -213,7 +212,7 @@ class PubSubRequest(generic.Stanza):
1462+ @type maxItems: L{int}.
1463+1464+ @ivar nodeIdentifier: Identifier of the node the request is about.
1465+- @type nodeIdentifier: L{unicode}
1466++ @type nodeIdentifier: L{str}
1467+1468+ @ivar nodeType: The type of node that should be created, or for which the
1469+ configuration is retrieved. C{'leaf'} or C{'collection'}.
1470+@@ -227,7 +226,7 @@ class PubSubRequest(generic.Stanza):
1471+ @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
1472+1473+ @ivar subscriptionIdentifier: Identifier for a specific subscription.
1474+- @type subscriptionIdentifier: L{unicode}
1475++ @type subscriptionIdentifier: L{str}
1476+1477+ @ivar subscriptions: Subscriptions to be modified, as a set of
1478+ L{Subscription}.
1479+@@ -235,7 +234,7 @@ class PubSubRequest(generic.Stanza):
1480+1481+ @ivar affiliations: Affiliations to be modified, as a dictionary of entity
1482+ (L{JID<twisted.words.protocols.jabber.jid.JID>} to affiliation
1483+- (L{unicode}).
1484++ (L{str}).
1485+ @type affiliations: L{dict}
1486+ """
1487+1488+@@ -277,7 +276,7 @@ class PubSubRequest(generic.Stanza):
1489+ }
1490+1491+ # Map request verb to request iq type and subelement name
1492+- _verbRequestMap = dict(((v, k) for k, v in iteritems(_requestVerbMap)))
1493++ _verbRequestMap = dict(((v, k) for k, v in _requestVerbMap.items()))
1494+1495+ # Map request verb to parameter handler names
1496+ _parameters = {
1497+@@ -487,7 +486,7 @@ class PubSubRequest(generic.Stanza):
1498+ Render maximum items into an items request.
1499+ """
1500+ if self.maxItems:
1501+- verbElement['max_items'] = unicode(self.maxItems)
1502++ verbElement['max_items'] = str(self.maxItems)
1503+1504+1505+ def _parse_subidOrNone(self, verbElement):
1506+@@ -648,7 +647,7 @@ class PubSubEvent(object):
1507+ @param recipient: The entity to which the notification was sent.
1508+ @type recipient: L{wokkel.pubsub.ItemsEvent}
1509+ @param nodeIdentifier: Identifier of the node the event pertains to.
1510+- @type nodeIdentifier: L{unicode}
1511++ @type nodeIdentifier: L{str}
1512+ @param headers: SHIM headers, see L{wokkel.shim.extractHeaders}.
1513+ @type headers: L{dict}
1514+ """
1515+@@ -772,7 +771,7 @@ class PubSubClient(XMPPHandler):
1516+ @param service: The publish subscribe service to create the node at.
1517+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
1518+ @param nodeIdentifier: Optional suggestion for the id of the node.
1519+- @type nodeIdentifier: L{unicode}
1520++ @type nodeIdentifier: L{str}
1521+ @param options: Optional node configuration options.
1522+ @type options: L{dict}
1523+ """
1524+@@ -807,7 +806,7 @@ class PubSubClient(XMPPHandler):
1525+ @param service: The publish subscribe service to delete the node from.
1526+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
1527+ @param nodeIdentifier: The identifier of the node.
1528+- @type nodeIdentifier: L{unicode}
1529++ @type nodeIdentifier: L{str}
1530+ """
1531+ request = PubSubRequest('delete')
1532+ request.recipient = service
1533+@@ -825,7 +824,7 @@ class PubSubClient(XMPPHandler):
1534+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
1535+1536+ @param nodeIdentifier: The identifier of the node.
1537+- @type nodeIdentifier: L{unicode}
1538++ @type nodeIdentifier: L{str}
1539+1540+ @param subscriber: The entity to subscribe to the node. This entity
1541+ will get notifications of new published items.
1542+@@ -877,13 +876,13 @@ class PubSubClient(XMPPHandler):
1543+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
1544+1545+ @param nodeIdentifier: The identifier of the node.
1546+- @type nodeIdentifier: L{unicode}
1547++ @type nodeIdentifier: L{str}
1548+1549+ @param subscriber: The entity to unsubscribe from the node.
1550+ @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
1551+1552+ @param subscriptionIdentifier: Optional subscription identifier.
1553+- @type subscriptionIdentifier: L{unicode}
1554++ @type subscriptionIdentifier: L{str}
1555+ """
1556+ request = PubSubRequest('unsubscribe')
1557+ request.recipient = service
1558+@@ -901,7 +900,7 @@ class PubSubClient(XMPPHandler):
1559+ @param service: The publish subscribe service that keeps the node.
1560+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
1561+ @param nodeIdentifier: The identifier of the node.
1562+- @type nodeIdentifier: L{unicode}
1563++ @type nodeIdentifier: L{str}
1564+ @param items: Optional list of L{Item}s to publish.
1565+ @type items: L{list}
1566+ """
1567+@@ -922,7 +921,7 @@ class PubSubClient(XMPPHandler):
1568+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
1569+1570+ @param nodeIdentifier: The identifier of the node.
1571+- @type nodeIdentifier: L{unicode}
1572++ @type nodeIdentifier: L{str}
1573+1574+ @param maxItems: Optional limit on the number of retrieved items.
1575+ @type maxItems: L{int}
1576+@@ -930,10 +929,10 @@ class PubSubClient(XMPPHandler):
1577+ @param subscriptionIdentifier: Optional subscription identifier. In
1578+ case the node has been subscribed to multiple times, this narrows
1579+ the results to the specific subscription.
1580+- @type subscriptionIdentifier: L{unicode}
1581++ @type subscriptionIdentifier: L{str}
1582+1583+ @param itemIdentifiers: Identifiers of the items to be retrieved.
1584+- @type itemIdentifiers: L{set} of L{unicode}
1585++ @type itemIdentifiers: L{set} of L{str}
1586+ """
1587+ request = PubSubRequest('items')
1588+ request.recipient = service
1589+@@ -965,13 +964,13 @@ class PubSubClient(XMPPHandler):
1590+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
1591+1592+ @param nodeIdentifier: The identifier of the node.
1593+- @type nodeIdentifier: L{unicode}
1594++ @type nodeIdentifier: L{str}
1595+1596+ @param subscriber: The entity subscribed to the node.
1597+ @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
1598+1599+ @param subscriptionIdentifier: Optional subscription identifier.
1600+- @type subscriptionIdentifier: L{unicode}
1601++ @type subscriptionIdentifier: L{str}
1602+1603+ @rtype: L{data_form.Form}
1604+ """
1605+@@ -1002,7 +1001,7 @@ class PubSubClient(XMPPHandler):
1606+ @type service: L{JID<twisted.words.protocols.jabber.jid.JID>}
1607+1608+ @param nodeIdentifier: The identifier of the node.
1609+- @type nodeIdentifier: L{unicode}
1610++ @type nodeIdentifier: L{str}
1611+1612+ @param subscriber: The entity subscribed to the node.
1613+ @type subscriber: L{JID<twisted.words.protocols.jabber.jid.JID>}
1614+@@ -1011,7 +1010,7 @@ class PubSubClient(XMPPHandler):
1615+ @type options: L{dict}.
1616+1617+ @param subscriptionIdentifier: Optional subscription identifier.
1618+- @type subscriptionIdentifier: L{unicode}
1619++ @type subscriptionIdentifier: L{str}
1620+ """
1621+ request = PubSubRequest('optionsSet')
1622+ request.recipient = service
1623+@@ -1356,7 +1355,7 @@ class PubSubService(XMPPHandler, IQHandlerMixin):
1624+ if request.nodeIdentifier:
1625+ affiliations['node'] = request.nodeIdentifier
1626+1627+- for entity, affiliation in iteritems(result):
1628++ for entity, affiliation in result.items():
1629+ item = affiliations.addElement('affiliation')
1630+ item['jid'] = entity.full()
1631+ item['affiliation'] = affiliation
1632+diff --git a/wokkel/server.py b/wokkel/server.py
1633+index 54517a2..fbd8452 100644
1634+--- a/wokkel/server.py
1635++++ b/wokkel/server.py
1636+@@ -22,7 +22,6 @@ from zope.interface import implementer
1637+ from twisted.internet import defer, reactor
1638+ from twisted.names.srvconnect import SRVConnector
1639+ from twisted.python import log, randbytes
1640+-from twisted.python.compat import iteritems, unicode
1641+ from twisted.words.protocols.jabber import error, ijabber, jid, xmlstream
1642+ from twisted.words.xish import domish
1643+1644+@@ -40,15 +39,15 @@ def generateKey(secret, receivingServer, originatingServer, streamID):
1645+1646+ @param secret: the shared secret known to the Originating Server and
1647+ Authoritive Server.
1648+- @type secret: L{unicode}
1649++ @type secret: L{str}
1650+ @param receivingServer: the Receiving Server host name.
1651+- @type receivingServer: L{unicode}
1652++ @type receivingServer: L{str}
1653+ @param originatingServer: the Originating Server host name.
1654+- @type originatingServer: L{unicode}
1655++ @type originatingServer: L{str}
1656+ @param streamID: the Stream ID as generated by the Receiving Server.
1657+- @type streamID: L{unicode}
1658++ @type streamID: L{str}
1659+ @return: hexadecimal digest of the generated key.
1660+- @type: C{str}
1661++ @type: L{str}
1662+ """
1663+1664+ hashObject = sha256()
1665+@@ -340,7 +339,7 @@ class XMPPServerListenAuthenticator(xmlstream.ListenAuthenticator):
1666+ try:
1667+ if xmlstream.NS_STREAMS != rootElement.uri or \
1668+ self.namespace != self.xmlstream.namespace or \
1669+- ('db', NS_DIALBACK) not in iteritems(rootElement.localPrefixes):
1670++ ('db', NS_DIALBACK) not in rootElement.localPrefixes.items():
1671+ raise error.StreamError('invalid-namespace')
1672+1673+ if targetDomain and targetDomain not in self.service.domains:
1674+@@ -379,7 +378,7 @@ class XMPPServerListenAuthenticator(xmlstream.ListenAuthenticator):
1675+ raise error.StreamError('invalid-from')
1676+1677+ streamID = verify.getAttribute('id', '')
1678+- key = unicode(verify)
1679++ key = str(verify)
1680+1681+ calculatedKey = generateKey(self.service.secret, receivingServer,
1682+ originatingServer, streamID)
1683+@@ -415,7 +414,7 @@ class XMPPServerListenAuthenticator(xmlstream.ListenAuthenticator):
1684+1685+ receivingServer = result['to']
1686+ originatingServer = result['from']
1687+- key = unicode(result)
1688++ key = str(result)
1689+1690+ d = self.service.validateConnection(receivingServer, originatingServer,
1691+ self.xmlstream.sid, key)
1692+diff --git a/wokkel/shim.py b/wokkel/shim.py
1693+index 3b12349..85a0848 100644
1694+--- a/wokkel/shim.py
1695++++ b/wokkel/shim.py
1696+@@ -12,7 +12,6 @@ U{XEP-0131<http://xmpp.org/extensions/xep-0131.html>}.
1697+1698+ from __future__ import division, absolute_import
1699+1700+-from twisted.python.compat import unicode
1701+ from twisted.words.xish import domish
1702+1703+ NS_SHIM = "http://jabber.org/protocol/shim"
1704+@@ -30,7 +29,7 @@ def extractHeaders(stanza):
1705+ @param stanza: The stanza to extract headers from.
1706+ @type stanza: L{Element<twisted.words.xish.domish.Element>}
1707+ @return: Headers as a mapping from header name to a list of values.
1708+- @rtype: C{dict}
1709++ @rtype: L{dict}
1710+ """
1711+ headers = {}
1712+1713+@@ -38,6 +37,6 @@ def extractHeaders(stanza):
1714+ 'headers', NS_SHIM):
1715+ for header in domish.generateElementsQNamed(element.children,
1716+ 'header', NS_SHIM):
1717+- headers.setdefault(header['name'], []).append(unicode(header))
1718++ headers.setdefault(header['name'], []).append(str(header))
1719+1720+ return headers
1721+diff --git a/wokkel/subprotocols.py b/wokkel/subprotocols.py
1722+index f0a6090..b4cde14 100644
1723+--- a/wokkel/subprotocols.py
1724++++ b/wokkel/subprotocols.py
1725+@@ -14,7 +14,6 @@ from zope.interface import implementer
1726+ from twisted.internet import defer
1727+ from twisted.internet.error import ConnectionDone
1728+ from twisted.python import failure, log
1729+-from twisted.python.compat import iteritems, itervalues
1730+ from twisted.python.deprecate import deprecatedModuleAttribute
1731+ from twisted.words.protocols.jabber import error, ijabber, xmlstream
1732+ from twisted.words.protocols.jabber.xmlstream import toResponse
1733+@@ -130,15 +129,15 @@ class StreamManager(XMPPHandlerCollection):
1734+ @ivar xmlstream: currently managed XML stream
1735+ @type xmlstream: L{XmlStream}
1736+ @ivar logTraffic: if true, log all traffic.
1737+- @type logTraffic: C{bool}
1738++ @type logTraffic: L{bool}
1739+ @ivar _initialized: Whether the stream represented by L{xmlstream} has
1740+ been initialized. This is used when caching outgoing
1741+ stanzas.
1742+- @type _initialized: C{bool}
1743++ @type _initialized: L{bool}
1744+ @ivar _packetQueue: internal buffer of unsent data. See L{send} for details.
1745+ @type _packetQueue: L{list}
1746+ @ivar timeout: Default IQ request timeout in seconds.
1747+- @type timeout: C{int}
1748++ @type timeout: L{int}
1749+ @ivar _reactor: A provider of L{IReactorTime} to track timeouts.
1750+ """
1751+ timeout = None
1752+@@ -277,7 +276,7 @@ class StreamManager(XMPPHandlerCollection):
1753+ # deferreds will never be fired.
1754+ iqDeferreds = self._iqDeferreds
1755+ self._iqDeferreds = {}
1756+- for d in itervalues(iqDeferreds):
1757++ for d in iqDeferreds.values():
1758+ d.errback(reason)
1759+1760+1761+@@ -420,7 +419,7 @@ class IQHandlerMixin(object):
1762+1763+ @cvar iqHandlers: Mapping from XPath queries (as a string) to the method
1764+ name that will handle requests that match the query.
1765+- @type iqHandlers: C{dict}
1766++ @type iqHandlers: L{dict}
1767+ """
1768+1769+ iqHandlers = None
1770+@@ -455,7 +454,7 @@ class IQHandlerMixin(object):
1771+ return error.StanzaError('internal-server-error').toResponse(iq)
1772+1773+ handler = None
1774+- for queryString, method in iteritems(self.iqHandlers):
1775++ for queryString, method in self.iqHandlers.items():
1776+ if xpath.internQuery(queryString).matches(iq):
1777+ handler = getattr(self, method)
1778+1779+diff --git a/wokkel/test/helpers.py b/wokkel/test/helpers.py
1780+index 102b3dc..c76a4a0 100644
1781+--- a/wokkel/test/helpers.py
1782++++ b/wokkel/test/helpers.py
1783+@@ -8,7 +8,6 @@ Unit test helpers.
1784+ from __future__ import division, absolute_import
1785+1786+ from twisted.internet import defer
1787+-from twisted.python.compat import iteritems
1788+ from twisted.words.xish import xpath
1789+ from twisted.words.xish.utility import EventDispatcher
1790+1791+@@ -79,14 +78,14 @@ class TestableRequestHandlerMixin(object):
1792+ Find a handler and call it directly.
1793+1794+ @param xml: XML stanza that may yield a handler being called.
1795+- @type xml: C{str}.
1796++ @type xml: L{str}.
1797+ @return: Deferred that fires with the result of a handler for this
1798+ stanza. If no handler was found, the deferred has its errback
1799+ called with a C{NotImplementedError} exception.
1800+ """
1801+ handler = None
1802+ iq = parseXml(xml)
1803+- for queryString, method in iteritems(self.service.iqHandlers):
1804++ for queryString, method in self.service.iqHandlers.items():
1805+ if xpath.internQuery(queryString).matches(iq):
1806+ handler = getattr(self.service, method)
1807+1808+diff --git a/wokkel/test/test_client.py b/wokkel/test/test_client.py
1809+index ef367f7..ef9adfd 100644
1810+--- a/wokkel/test/test_client.py
1811++++ b/wokkel/test/test_client.py
1812+@@ -8,6 +8,7 @@ Tests for L{wokkel.client}.
1813+ from __future__ import division, absolute_import
1814+1815+ from twisted.internet import defer
1816++from twisted.python.compat import nativeString
1817+ from twisted.trial import unittest
1818+ from twisted.words.protocols.jabber import xmlstream
1819+ from twisted.words.protocols.jabber.client import XMPPAuthenticator
1820+@@ -152,7 +153,7 @@ class ClientCreatorTest(unittest.TestCase):
1821+1822+ def cb(connector):
1823+ self.assertEqual('xmpp-client', connector.service)
1824+- self.assertEqual('example.org', connector.domain)
1825++ self.assertEqual('example.org', nativeString(connector.domain))
1826+ self.assertEqual(factory, connector.factory)
1827+1828+ def connect(connector):
1829+diff --git a/wokkel/test/test_data_form.py b/wokkel/test/test_data_form.py
1830+index 60e36f4..246f1c5 100644
1831+--- a/wokkel/test/test_data_form.py
1832++++ b/wokkel/test/test_data_form.py
1833+@@ -10,7 +10,6 @@ from __future__ import division, absolute_import
1834+ from zope.interface import verify
1835+ from zope.interface.common.mapping import IIterableMapping
1836+1837+-from twisted.python.compat import unicode, _PY3
1838+ from twisted.trial import unittest
1839+ from twisted.words.xish import domish
1840+ from twisted.words.protocols.jabber import jid
1841+@@ -34,7 +33,7 @@ class OptionTest(unittest.TestCase):
1842+ self.assertEqual('option', element.name)
1843+ self.assertEqual(NS_X_DATA, element.uri)
1844+ self.assertEqual(NS_X_DATA, element.value.uri)
1845+- self.assertEqual('value', unicode(element.value))
1846++ self.assertEqual('value', str(element.value))
1847+ self.assertFalse(element.hasAttribute('label'))
1848+1849+1850+@@ -48,7 +47,7 @@ class OptionTest(unittest.TestCase):
1851+ self.assertEqual('option', element.name)
1852+ self.assertEqual(NS_X_DATA, element.uri)
1853+ self.assertEqual(NS_X_DATA, element.value.uri)
1854+- self.assertEqual('value', unicode(element.value))
1855++ self.assertEqual('value', str(element.value))
1856+ self.assertEqual('label', element['label'])
1857+1858+1859+@@ -225,7 +224,7 @@ class FieldTest(unittest.TestCase):
1860+ child = element.children[0]
1861+ self.assertEqual('desc', child.name)
1862+ self.assertEqual(NS_X_DATA, child.uri)
1863+- self.assertEqual(u'My desc', unicode(child))
1864++ self.assertEqual(u'My desc', str(child))
1865+1866+1867+ def test_toElementRequired(self):
1868+@@ -248,7 +247,7 @@ class FieldTest(unittest.TestCase):
1869+ field = data_form.Field(fieldType='jid-single', var='test',
1870+ value=jid.JID(u'test@example.org'))
1871+ element = field.toElement()
1872+- self.assertEqual(u'test@example.org', unicode(element.value))
1873++ self.assertEqual(u'test@example.org', str(element.value))
1874+1875+1876+ def test_toElementJIDTextSingle(self):
1877+@@ -258,7 +257,7 @@ class FieldTest(unittest.TestCase):
1878+ field = data_form.Field(fieldType='text-single', var='test',
1879+ value=jid.JID(u'test@example.org'))
1880+ element = field.toElement()
1881+- self.assertEqual(u'test@example.org', unicode(element.value))
1882++ self.assertEqual(u'test@example.org', str(element.value))
1883+1884+1885+ def test_toElementBoolean(self):
1886+@@ -268,7 +267,7 @@ class FieldTest(unittest.TestCase):
1887+ field = data_form.Field(fieldType='boolean', var='test',
1888+ value=True)
1889+ element = field.toElement()
1890+- self.assertEqual(u'true', unicode(element.value))
1891++ self.assertEqual(u'true', str(element.value))
1892+1893+1894+ def test_toElementBooleanTextSingle(self):
1895+@@ -277,7 +276,7 @@ class FieldTest(unittest.TestCase):
1896+ """
1897+ field = data_form.Field(var='test', value=True)
1898+ element = field.toElement()
1899+- self.assertEqual(u'true', unicode(element.value))
1900++ self.assertEqual(u'true', str(element.value))
1901+1902+1903+ def test_toElementNoType(self):
1904+@@ -396,7 +395,7 @@ class FieldTest(unittest.TestCase):
1905+1906+ def test_fromElementValueTextSingle(self):
1907+ """
1908+- Parsed text-single field values should be of type C{unicode}.
1909++ Parsed text-single field values should be of type L{str}.
1910+ """
1911+ element = domish.Element((NS_X_DATA, 'field'))
1912+ element['type'] = 'text-single'
1913+@@ -407,7 +406,7 @@ class FieldTest(unittest.TestCase):
1914+1915+ def test_fromElementValueJID(self):
1916+ """
1917+- Parsed jid-single field values should be of type C{unicode}.
1918++ Parsed jid-single field values should be of type L{str}.
1919+ """
1920+ element = domish.Element((NS_X_DATA, 'field'))
1921+ element['type'] = 'jid-single'
1922+@@ -418,7 +417,7 @@ class FieldTest(unittest.TestCase):
1923+1924+ def test_fromElementValueJIDMalformed(self):
1925+ """
1926+- Parsed jid-single field values should be of type C{unicode}.
1927++ Parsed jid-single field values should be of type L{str}.
1928+1929+ No validation should be done at this point, so invalid JIDs should
1930+ also be passed as-is.
1931+@@ -432,7 +431,7 @@ class FieldTest(unittest.TestCase):
1932+1933+ def test_fromElementValueBoolean(self):
1934+ """
1935+- Parsed boolean field values should be of type C{unicode}.
1936++ Parsed boolean field values should be of type L{str}.
1937+ """
1938+ element = domish.Element((NS_X_DATA, 'field'))
1939+ element['type'] = 'boolean'
1940+@@ -561,7 +560,7 @@ class FormTest(unittest.TestCase):
1941+ title = elements[0]
1942+ self.assertEqual('title', title.name)
1943+ self.assertEqual(NS_X_DATA, title.uri)
1944+- self.assertEqual('Bot configuration', unicode(title))
1945++ self.assertEqual('Bot configuration', str(title))
1946+1947+1948+ def test_toElementInstructions(self):
1949+@@ -576,7 +575,7 @@ class FormTest(unittest.TestCase):
1950+ instructions = elements[0]
1951+ self.assertEqual('instructions', instructions.name)
1952+ self.assertEqual(NS_X_DATA, instructions.uri)
1953+- self.assertEqual('Fill out this form!', unicode(instructions))
1954++ self.assertEqual('Fill out this form!', str(instructions))
1955+1956+1957+ def test_toElementInstructionsMultiple(self):
1958+@@ -593,10 +592,10 @@ class FormTest(unittest.TestCase):
1959+ instructions2 = elements[1]
1960+ self.assertEqual('instructions', instructions1.name)
1961+ self.assertEqual(NS_X_DATA, instructions1.uri)
1962+- self.assertEqual('Fill out this form!', unicode(instructions1))
1963++ self.assertEqual('Fill out this form!', str(instructions1))
1964+ self.assertEqual('instructions', instructions2.name)
1965+ self.assertEqual(NS_X_DATA, instructions2.uri)
1966+- self.assertEqual('no really', unicode(instructions2))
1967++ self.assertEqual('no really', str(instructions2))
1968+1969+1970+ def test_toElementFormType(self):
1971+@@ -613,7 +612,7 @@ class FormTest(unittest.TestCase):
1972+ self.assertEqual(NS_X_DATA, formTypeField.uri)
1973+ self.assertEqual('FORM_TYPE', formTypeField['var'])
1974+ self.assertEqual('hidden', formTypeField['type'])
1975+- self.assertEqual('jabber:bot', unicode(formTypeField.value))
1976++ self.assertEqual('jabber:bot', str(formTypeField.value))
1977+1978+1979+ def test_toElementFields(self):
1980+@@ -1091,7 +1090,7 @@ class FormTest(unittest.TestCase):
1981+ self.assertNotIn('features', form)
1982+1983+1984+- def test_iterkeys(self):
1985++ def test_keys(self):
1986+ """
1987+ Iterating over the keys of a form yields all field names.
1988+ """
1989+@@ -1101,10 +1100,10 @@ class FormTest(unittest.TestCase):
1990+ values=['news', 'search'])]
1991+ form = data_form.Form('submit', fields=fields)
1992+ self.assertEqual(set(['botname', 'public', 'features']),
1993+- set(form.iterkeys()))
1994++ set(form.keys()))
1995+1996+1997+- def test_itervalues(self):
1998++ def test_values(self):
1999+ """
2000+ Iterating over the values of a form yields all field values.
2001+ """
2002+@@ -1112,63 +1111,19 @@ class FormTest(unittest.TestCase):
2003+ data_form.Field('boolean', var='public', value=True)]
2004+ form = data_form.Form('submit', fields=fields)
2005+ self.assertEqual(set(['The Jabber Bot', True]),
2006+- set(form.itervalues()))
2007+-
2008+-
2009+- def test_iteritems(self):
2010+- """
2011+- Iterating over the values of a form yields all item tuples.
2012+- """
2013+- fields = [data_form.Field(var='botname', value='The Jabber Bot'),
2014+- data_form.Field('boolean', var='public', value=True)]
2015+- form = data_form.Form('submit', fields=fields)
2016+- self.assertEqual(set([('botname', 'The Jabber Bot'),
2017+- ('public', True)]),
2018+- set(form.iteritems()))
2019+-
2020+-
2021+- def test_keys(self):
2022+- """
2023+- Getting the keys of a form yields a list of field names.
2024+- """
2025+- fields = [data_form.Field(var='botname', value='The Jabber Bot'),
2026+- data_form.Field('boolean', var='public', value=True),
2027+- data_form.Field('list-multi', var='features',
2028+- values=['news', 'search'])]
2029+- form = data_form.Form('submit', fields=fields)
2030+- keys = form.keys()
2031+- if not _PY3:
2032+- self.assertIsInstance(keys, list)
2033+- self.assertEqual(set(['botname', 'public', 'features']),
2034+- set(keys))
2035+-
2036+-
2037+- def test_values(self):
2038+- """
2039+- Getting the values of a form yields a list of field values.
2040+- """
2041+- fields = [data_form.Field(var='botname', value='The Jabber Bot'),
2042+- data_form.Field('boolean', var='public', value=True)]
2043+- form = data_form.Form('submit', fields=fields)
2044+- values = form.values()
2045+- if not _PY3:
2046+- self.assertIsInstance(values, list)
2047+- self.assertEqual(set(['The Jabber Bot', True]), set(values))
2048++ set(form.values()))
2049+2050+2051+ def test_items(self):
2052+ """
2053+- Iterating over the values of a form yields a list of all item tuples.
2054++ Iterating over the values of a form yields all item tuples.
2055+ """
2056+ fields = [data_form.Field(var='botname', value='The Jabber Bot'),
2057+ data_form.Field('boolean', var='public', value=True)]
2058+ form = data_form.Form('submit', fields=fields)
2059+- items = form.items()
2060+- if not _PY3:
2061+- self.assertIsInstance(items, list)
2062+ self.assertEqual(set([('botname', 'The Jabber Bot'),
2063+ ('public', True)]),
2064+- set(items))
2065++ set(form.items()))
2066+2067+2068+ def test_getValues(self):
2069+diff --git a/wokkel/test/test_generic.py b/wokkel/test/test_generic.py
2070+index 94c39e5..4e4ab45 100644
2071+--- a/wokkel/test/test_generic.py
2072++++ b/wokkel/test/test_generic.py
2073+@@ -7,19 +7,12 @@ Tests for L{wokkel.generic}.
2074+2075+ from __future__ import division, absolute_import
2076+2077+-import re
2078+-
2079+ from zope.interface.verify import verifyObject
2080+2081+-from twisted.python import deprecate
2082+-from twisted.python.compat import unicode
2083+ from twisted.trial import unittest
2084+-from twisted.trial.util import suppress as SUPPRESS
2085+ from twisted.words.xish import domish
2086+ from twisted.words.protocols.jabber.jid import JID
2087+2088+-from incremental import Version
2089+-
2090+ from wokkel import generic
2091+ from wokkel.iwokkel import IDisco
2092+ from wokkel.test.helpers import XmlStreamStub
2093+@@ -66,11 +59,11 @@ class VersionHandlerTest(unittest.TestCase):
2094+ elements = list(domish.generateElementsQNamed(response.query.children,
2095+ 'name', NS_VERSION))
2096+ self.assertEquals(1, len(elements))
2097+- self.assertEquals('Test', unicode(elements[0]))
2098++ self.assertEquals('Test', str(elements[0]))
2099+ elements = list(domish.generateElementsQNamed(response.query.children,
2100+ 'version', NS_VERSION))
2101+ self.assertEquals(1, len(elements))
2102+- self.assertEquals('0.1.0', unicode(elements[0]))
2103++ self.assertEquals('0.1.0', str(elements[0]))
2104+2105+2106+2107+@@ -314,67 +307,3 @@ class RequestTest(unittest.TestCase):
2108+2109+ request = SetRequest()
2110+ self.assertEqual('set', request.stanzaType)
2111+-
2112+-
2113+-
2114+-class PrepareIDNNameTests(unittest.TestCase):
2115+- """
2116+- Tests for L{wokkel.generic.prepareIDNName}.
2117+- """
2118+-
2119+- suppress = [SUPPRESS(category=DeprecationWarning,
2120+- message=re.escape(
2121+- deprecate.getDeprecationWarningString(
2122+- generic.prepareIDNName,
2123+- Version("wokkel", 18, 0, 0),
2124+- replacement="unicode.encode('idna')")))]
2125+-
2126+-
2127+- def test_deprecated(self):
2128+- """
2129+- prepareIDNName is deprecated.
2130+- """
2131+- self.callDeprecated((Version("wokkel", 18, 0, 0),
2132+- "unicode.encode('idna')"),
2133+- generic.prepareIDNName, ("example.com"))
2134+- test_deprecated.suppress = []
2135+-
2136+-
2137+- def test_unicode(self):
2138+- """
2139+- A unicode all-ASCII name is converted to an ASCII byte string.
2140+- """
2141+- name = u"example.com"
2142+- result = generic.prepareIDNName(name)
2143+- self.assertEqual(b"example.com", result)
2144+-
2145+-
2146+- def test_unicodeNonASCII(self):
2147+- """
2148+- A unicode with non-ASCII is converted to its ACE equivalent.
2149+- """
2150+- name = u"\u00e9chec.example.com"
2151+- result = generic.prepareIDNName(name)
2152+- self.assertEqual(b"xn--chec-9oa.example.com", result)
2153+-
2154+-
2155+- def test_unicodeHalfwidthIdeographicFullStop(self):
2156+- """
2157+- Exotic dots in unicode names are converted to Full Stop.
2158+- """
2159+- name = u"\u00e9chec.example\uff61com"
2160+- result = generic.prepareIDNName(name)
2161+- self.assertEqual(b"xn--chec-9oa.example.com", result)
2162+-
2163+-
2164+- def test_unicodeTrailingDot(self):
2165+- """
2166+- Unicode names with trailing dots retain the trailing dot.
2167+-
2168+- L{encodings.idna.ToASCII} doesn't allow the empty string as the input,
2169+- hence the implementation needs to strip a trailing dot, and re-add it
2170+- after encoding the labels.
2171+- """
2172+- name = u"example.com."
2173+- result = generic.prepareIDNName(name)
2174+- self.assertEqual(b"example.com.", result)
2175+diff --git a/wokkel/test/test_muc.py b/wokkel/test/test_muc.py
2176+index f690d05..282a8a1 100644
2177+--- a/wokkel/test/test_muc.py
2178++++ b/wokkel/test/test_muc.py
2179+@@ -14,7 +14,6 @@ from zope.interface import verify
2180+2181+ from twisted.trial import unittest
2182+ from twisted.internet import defer, task
2183+-from twisted.python.compat import iteritems, unicode
2184+ from twisted.words.xish import domish, xpath
2185+ from twisted.words.protocols.jabber.jid import JID
2186+ from twisted.words.protocols.jabber.error import StanzaError
2187+@@ -81,7 +80,7 @@ class StatusCodeTest(unittest.TestCase):
2188+ 332: 'removed-shutdown',
2189+ }
2190+2191+- for code, condition in iteritems(codes):
2192++ for code, condition in codes.items():
2193+ constantName = condition.replace('-', '_').upper()
2194+ self.assertEqual(getattr(muc.STATUS_CODE, constantName),
2195+ muc.STATUS_CODE.lookupByValue(code))
2196+@@ -757,7 +756,7 @@ class MUCClientProtocolTest(unittest.TestCase):
2197+ self.assertEquals('message', message.name)
2198+ self.assertEquals(self.roomJID.full(), message.getAttribute('to'))
2199+ self.assertEquals('groupchat', message.getAttribute('type'))
2200+- self.assertEquals(u'This is a test', unicode(message.body))
2201++ self.assertEquals(u'This is a test', str(message.body))
2202+2203+2204+ def test_chat(self):
2205+@@ -773,7 +772,7 @@ class MUCClientProtocolTest(unittest.TestCase):
2206+ self.assertEquals('message', message.name)
2207+ self.assertEquals(otherOccupantJID.full(), message.getAttribute('to'))
2208+ self.assertEquals('chat', message.getAttribute('type'))
2209+- self.assertEquals(u'This is a test', unicode(message.body))
2210++ self.assertEquals(u'This is a test', str(message.body))
2211+2212+2213+ def test_subject(self):
2214+@@ -787,7 +786,7 @@ class MUCClientProtocolTest(unittest.TestCase):
2215+ self.assertEquals('message', message.name)
2216+ self.assertEquals(self.roomJID.full(), message.getAttribute('to'))
2217+ self.assertEquals('groupchat', message.getAttribute('type'))
2218+- self.assertEquals(u'This is a test', unicode(message.subject))
2219++ self.assertEquals(u'This is a test', str(message.subject))
2220+2221+2222+ def test_invite(self):
2223+@@ -806,7 +805,7 @@ class MUCClientProtocolTest(unittest.TestCase):
2224+ self.assertEquals(muc.NS_MUC_USER, message.x.invite.uri)
2225+ self.assertEquals(invitee.full(), message.x.invite.getAttribute('to'))
2226+ self.assertEquals(muc.NS_MUC_USER, message.x.invite.reason.uri)
2227+- self.assertEquals(u'This is a test', unicode(message.x.invite.reason))
2228++ self.assertEquals(u'This is a test', str(message.x.invite.reason))
2229+2230+2231+ def test_getRegisterForm(self):
2232+@@ -1399,7 +1398,7 @@ class MUCClientProtocolTest(unittest.TestCase):
2233+ nodes = xpath.queryForNodes(query, iq)
2234+ self.assertNotIdentical(None, nodes, 'Bad configure request')
2235+ destroy = nodes[0]
2236+- self.assertEquals('Time to leave', unicode(destroy.reason))
2237++ self.assertEquals('Time to leave', str(destroy.reason))
2238+2239+ response = toResponse(iq, 'result')
2240+ self.stub.send(response)
2241+diff --git a/wokkel/test/test_server.py b/wokkel/test/test_server.py
2242+index 3e3c923..1efb6e5 100644
2243+--- a/wokkel/test/test_server.py
2244++++ b/wokkel/test/test_server.py
2245+@@ -8,7 +8,11 @@ Tests for L{wokkel.server}.
2246+ from __future__ import division, absolute_import
2247+ from twisted.internet import defer
2248+ from twisted.python import failure
2249+-from twisted.test.proto_helpers import StringTransport
2250++try:
2251++ from twisted.internet.testing import StringTransport
2252++except ImportError:
2253++ from twisted.test.proto_helpers import StringTransport
2254++
2255+ from twisted.trial import unittest
2256+ from twisted.words.protocols.jabber import error, jid, xmlstream
2257+ from twisted.words.xish import domish
2258+diff --git a/wokkel/test/test_shim.py b/wokkel/test/test_shim.py
2259+index ded4679..d3b76cf 100644
2260+--- a/wokkel/test/test_shim.py
2261++++ b/wokkel/test/test_shim.py
2262+@@ -9,7 +9,6 @@ Tests for {wokkel.shim}.
2263+2264+ from __future__ import division, absolute_import
2265+2266+-from twisted.python.compat import unicode
2267+ from twisted.trial import unittest
2268+2269+ from wokkel import shim
2270+@@ -36,7 +35,7 @@ class HeadersTest(unittest.TestCase):
2271+ self.assertEquals(NS_SHIM, header.uri)
2272+ self.assertEquals('header', header.name)
2273+ self.assertEquals('Urgency', header['name'])
2274+- self.assertEquals('high', unicode(header))
2275++ self.assertEquals('high', str(header))
2276+2277+2278+ def test_headerRepeated(self):
2279+@@ -47,7 +46,7 @@ class HeadersTest(unittest.TestCase):
2280+ ('Collection', 'node2')])
2281+ elements = list(headers.elements())
2282+ self.assertEquals(2, len(elements))
2283+- collections = set((unicode(element) for element in elements
2284++ collections = set((str(element) for element in elements
2285+ if element['name'] == 'Collection'))
2286+ self.assertIn('node1', collections)
2287+ self.assertIn('node2', collections)
2288+diff --git a/wokkel/test/test_xmppim.py b/wokkel/test/test_xmppim.py
2289+index faab8ed..0d4fdbf 100644
2290+--- a/wokkel/test/test_xmppim.py
2291++++ b/wokkel/test/test_xmppim.py
2292+@@ -9,7 +9,6 @@ from __future__ import division, absolute_import
2293+2294+ from twisted.internet import defer
2295+ from twisted.trial import unittest
2296+-from twisted.python.compat import unicode
2297+ from twisted.words.protocols.jabber import error
2298+ from twisted.words.protocols.jabber.jid import JID
2299+ from twisted.words.protocols.jabber.xmlstream import toResponse
2300+@@ -55,7 +54,7 @@ class PresenceClientProtocolTest(unittest.TestCase):
2301+ self.assertEquals(None, presence.uri)
2302+ self.assertEquals("user@example.com", presence.getAttribute('to'))
2303+ self.assertEquals("unavailable", presence.getAttribute('type'))
2304+- self.assertEquals("Disconnected", unicode(presence.status))
2305++ self.assertEquals("Disconnected", str(presence.status))
2306+2307+ def test_unavailableBroadcast(self):
2308+ """
2309+@@ -298,9 +297,9 @@ class PresenceProtocolTest(unittest.TestCase):
2310+ element = self.output[-1]
2311+ self.assertEquals("user@example.com", element.getAttribute('to'))
2312+ self.assertIdentical(None, element.getAttribute('type'))
2313+- self.assertEquals(u'chat', unicode(element.show))
2314+- self.assertEquals(u'Talk to me!', unicode(element.status))
2315+- self.assertEquals(u'50', unicode(element.priority))
2316++ self.assertEquals(u'chat', str(element.show))
2317++ self.assertEquals(u'Talk to me!', str(element.status))
2318++ self.assertEquals(u'50', str(element.priority))
2319+2320+ def test_availableLanguages(self):
2321+ """
2322+@@ -314,19 +313,19 @@ class PresenceProtocolTest(unittest.TestCase):
2323+ element = self.output[-1]
2324+ self.assertEquals("user@example.com", element.getAttribute('to'))
2325+ self.assertIdentical(None, element.getAttribute('type'))
2326+- self.assertEquals(u'chat', unicode(element.show))
2327++ self.assertEquals(u'chat', str(element.show))
2328+2329+ statuses = {}
2330+ for status in element.elements():
2331+ if status.name == 'status':
2332+ lang = status.getAttribute((NS_XML, 'lang'))
2333+- statuses[lang] = unicode(status)
2334++ statuses[lang] = str(status)
2335+2336+ self.assertIn(None, statuses)
2337+ self.assertEquals(u'Talk to me!', statuses[None])
2338+ self.assertIn('nl', statuses)
2339+ self.assertEquals(u'Praat met me!', statuses['nl'])
2340+- self.assertEquals(u'50', unicode(element.priority))
2341++ self.assertEquals(u'50', str(element.priority))
2342+2343+2344+ def test_availableSender(self):
2345+@@ -363,7 +362,7 @@ class PresenceProtocolTest(unittest.TestCase):
2346+ self.assertEquals(None, element.uri)
2347+ self.assertEquals("user@example.com", element.getAttribute('to'))
2348+ self.assertEquals("unavailable", element.getAttribute('type'))
2349+- self.assertEquals("Disconnected", unicode(element.status))
2350++ self.assertEquals("Disconnected", str(element.status))
2351+2352+2353+ def test_unavailableBroadcast(self):
2354+@@ -568,7 +567,7 @@ class RosterItemTest(unittest.TestCase):
2355+ foundGroups = set()
2356+ for child in element.elements():
2357+ if child.uri == NS_ROSTER and child.name == 'group':
2358+- foundGroups.add(unicode(child))
2359++ foundGroups.add(str(child))
2360+2361+ self.assertEqual(groups, foundGroups)
2362+2363+diff --git a/wokkel/xmppim.py b/wokkel/xmppim.py
2364+index e6af929..683577b 100644
2365+--- a/wokkel/xmppim.py
2366++++ b/wokkel/xmppim.py
2367+@@ -15,7 +15,6 @@ from __future__ import division, absolute_import
2368+ import warnings
2369+2370+ from twisted.internet import defer
2371+-from twisted.python.compat import iteritems, itervalues, unicode
2372+ from twisted.words.protocols.jabber import error
2373+ from twisted.words.protocols.jabber.jid import JID
2374+ from twisted.words.xish import domish
2375+@@ -48,20 +47,20 @@ class AvailablePresence(Presence):
2376+ self.addElement('show', content=show)
2377+2378+ if statuses is not None:
2379+- for lang, status in iteritems(statuses):
2380++ for lang, status in statuses.items():
2381+ s = self.addElement('status', content=status)
2382+ if lang:
2383+ s[(NS_XML, "lang")] = lang
2384+2385+ if priority != 0:
2386+- self.addElement('priority', content=unicode(int(priority)))
2387++ self.addElement('priority', content=str(int(priority)))
2388+2389+ class UnavailablePresence(Presence):
2390+ def __init__(self, to=None, statuses=None):
2391+ Presence.__init__(self, to, type='unavailable')
2392+2393+ if statuses is not None:
2394+- for lang, status in iteritems(statuses):
2395++ for lang, status in statuses.items():
2396+ s = self.addElement('status', content=status)
2397+ if lang:
2398+ s[(NS_XML, "lang")] = lang
2399+@@ -76,7 +75,7 @@ class PresenceClientProtocol(XMPPHandler):
2400+ for element in presence.elements():
2401+ if element.name == 'status':
2402+ lang = element.getAttribute((NS_XML, 'lang'))
2403+- text = unicode(element)
2404++ text = str(element)
2405+ statuses[lang] = text
2406+ return statuses
2407+2408+@@ -92,14 +91,14 @@ class PresenceClientProtocol(XMPPHandler):
2409+ def _onPresenceAvailable(self, presence):
2410+ entity = JID(presence["from"])
2411+2412+- show = unicode(presence.show or '')
2413++ show = str(presence.show or '')
2414+ if show not in ['away', 'xa', 'chat', 'dnd']:
2415+ show = None
2416+2417+ statuses = self._getStatuses(presence)
2418+2419+ try:
2420+- priority = int(unicode(presence.priority or '')) or 0
2421++ priority = int(str(presence.priority or '')) or 0
2422+ except ValueError:
2423+ priority = 0
2424+2425+@@ -133,14 +132,14 @@ class PresenceClientProtocol(XMPPHandler):
2426+ @type entity: {JID}
2427+ @param show: detailed presence information. One of C{'away'}, C{'xa'},
2428+ C{'chat'}, C{'dnd'} or C{None}.
2429+- @type show: C{str} or C{NoneType}
2430++ @type show: L{str} or C{NoneType}
2431+ @param statuses: dictionary of natural language descriptions of the
2432+ availability status, keyed by the language
2433+ descriptor. A status without a language
2434+ specified, is keyed with C{None}.
2435+- @type statuses: C{dict}
2436++ @type statuses: L{dict}
2437+ @param priority: priority level of the resource.
2438+- @type priority: C{int}
2439++ @type priority: L{int}
2440+ """
2441+2442+ def unavailableReceived(self, entity, statuses=None):
2443+@@ -153,7 +152,7 @@ class PresenceClientProtocol(XMPPHandler):
2444+ availability status, keyed by the language
2445+ descriptor. A status without a language
2446+ specified, is keyed with C{None}.
2447+- @type statuses: C{dict}
2448++ @type statuses: L{dict}
2449+ """
2450+2451+ def subscribedReceived(self, entity):
2452+@@ -196,14 +195,14 @@ class PresenceClientProtocol(XMPPHandler):
2453+ @type entity: {JID}
2454+ @param show: optional detailed presence information. One of C{'away'},
2455+ C{'xa'}, C{'chat'}, C{'dnd'}.
2456+- @type show: C{str}
2457++ @type show: L{str}
2458+ @param statuses: dictionary of natural language descriptions of the
2459+ availability status, keyed by the language
2460+ descriptor. A status without a language
2461+ specified, is keyed with C{None}.
2462+- @type statuses: C{dict}
2463++ @type statuses: L{dict}
2464+ @param priority: priority level of the resource.
2465+- @type priority: C{int}
2466++ @type priority: L{int}
2467+ """
2468+ self.send(AvailablePresence(entity, show, statuses, priority))
2469+2470+@@ -217,7 +216,7 @@ class PresenceClientProtocol(XMPPHandler):
2471+ availability status, keyed by the language
2472+ descriptor. A status without a language
2473+ specified, is keyed with C{None}.
2474+- @type statuses: C{dict}
2475++ @type statuses: L{dict}
2476+ """
2477+ self.send(UnavailablePresence(entity, statuses))
2478+2479+@@ -275,19 +274,19 @@ class AvailabilityPresence(BasePresence):
2480+ L{SubscriptionPresence}).
2481+2482+ @ivar available: The availability being communicated.
2483+- @type available: C{bool}
2484++ @type available: L{bool}
2485+ @ivar show: More specific availability. Can be one of C{'chat'}, C{'away'},
2486+ C{'xa'}, C{'dnd'} or C{None}.
2487+- @type show: C{str} or C{NoneType}
2488++ @type show: L{str} or C{NoneType}
2489+ @ivar statuses: Natural language texts to detail the (un)availability.
2490+ These are represented as a mapping from language code
2491+- (C{str} or C{None}) to the corresponding text (C{unicode}).
2492++ (L{str} or C{None}) to the corresponding text (L{str}).
2493+ If the key is C{None}, the associated text is in the
2494+ default language.
2495+- @type statuses: C{dict}
2496++ @type statuses: L{dict}
2497+ @ivar priority: Priority level for this resource. Must be between -128 and
2498+ 127. Defaults to 0.
2499+- @type priority: C{int}
2500++ @type priority: L{int}
2501+ """
2502+2503+ childParsers = {(None, 'show'): '_childParser_show',
2504+@@ -309,7 +308,7 @@ class AvailabilityPresence(BasePresence):
2505+ if None in self.statuses:
2506+ return self.statuses[None]
2507+ elif self.statuses:
2508+- for status in itervalues(self.status):
2509++ for status in self.status.values():
2510+ return status
2511+ else:
2512+ return None
2513+@@ -318,20 +317,20 @@ class AvailabilityPresence(BasePresence):
2514+2515+2516+ def _childParser_show(self, element):
2517+- show = unicode(element)
2518++ show = str(element)
2519+ if show in ('chat', 'away', 'xa', 'dnd'):
2520+ self.show = show
2521+2522+2523+ def _childParser_status(self, element):
2524+ lang = element.getAttribute((NS_XML, 'lang'), None)
2525+- text = unicode(element)
2526++ text = str(element)
2527+ self.statuses[lang] = text
2528+2529+2530+ def _childParser_priority(self, element):
2531+ try:
2532+- self.priority = int(unicode(element))
2533++ self.priority = int(str(element))
2534+ except ValueError:
2535+ pass
2536+2537+@@ -353,9 +352,9 @@ class AvailabilityPresence(BasePresence):
2538+ if self.show in ('chat', 'away', 'xa', 'dnd'):
2539+ presence.addElement('show', content=self.show)
2540+ if self.priority != 0:
2541+- presence.addElement('priority', content=unicode(self.priority))
2542++ presence.addElement('priority', content=str(self.priority))
2543+2544+- for lang, text in iteritems(self.statuses):
2545++ for lang, text in self.statuses.items():
2546+ status = presence.addElement('status', content=text)
2547+ if lang:
2548+ status[(NS_XML, 'lang')] = lang
2549+@@ -400,7 +399,7 @@ class BasePresenceProtocol(XMPPHandler):
2550+2551+ @cvar presenceTypeParserMap: Maps presence stanza types to their respective
2552+ stanza parser classes (derived from L{Stanza}).
2553+- @type presenceTypeParserMap: C{dict}
2554++ @type presenceTypeParserMap: L{dict}
2555+ """
2556+2557+ presenceTypeParserMap = {}
2558+@@ -515,15 +514,15 @@ class PresenceProtocol(BasePresenceProtocol):
2559+2560+ @param show: Optional detailed presence information. One of C{'away'},
2561+ C{'xa'}, C{'chat'}, C{'dnd'}.
2562+- @type show: C{str}
2563++ @type show: L{str}
2564+2565+ @param statuses: Mapping of natural language descriptions of the
2566+ availability status, keyed by the language descriptor. A status
2567+ without a language specified, is keyed with C{None}.
2568+- @type statuses: C{dict}
2569++ @type statuses: L{dict}
2570+2571+ @param priority: priority level of the resource.
2572+- @type priority: C{int}
2573++ @type priority: L{int}
2574+ """
2575+ presence = AvailabilityPresence(recipient=recipient, sender=sender,
2576+ show=show, statuses=statuses,
2577+@@ -541,7 +540,7 @@ class PresenceProtocol(BasePresenceProtocol):
2578+ @param statuses: dictionary of natural language descriptions of the
2579+ availability status, keyed by the language descriptor. A status
2580+ without a language specified, is keyed with C{None}.
2581+- @type statuses: C{dict}
2582++ @type statuses: L{dict}
2583+ """
2584+ presence = AvailabilityPresence(recipient=recipient, sender=sender,
2585+ available=False, statuses=statuses)
2586+@@ -617,25 +616,25 @@ class RosterItem(object):
2587+ @ivar entity: The JID of the contact.
2588+ @type entity: L{JID}
2589+ @ivar name: The associated nickname for this contact.
2590+- @type name: C{unicode}
2591++ @type name: L{str}
2592+ @ivar subscriptionTo: Subscription state to contact's presence. If C{True},
2593+ the roster owner is subscribed to the presence
2594+ information of the contact.
2595+- @type subscriptionTo: C{bool}
2596++ @type subscriptionTo: L{bool}
2597+ @ivar subscriptionFrom: Contact's subscription state. If C{True}, the
2598+ contact is subscribed to the presence information
2599+ of the roster owner.
2600+- @type subscriptionFrom: C{bool}
2601++ @type subscriptionFrom: L{bool}
2602+ @ivar pendingOut: Whether the subscription request to this contact is
2603+ pending.
2604+- @type pendingOut: C{bool}
2605++ @type pendingOut: L{bool}
2606+ @ivar groups: Set of groups this contact is categorized in. Groups are
2607+- represented by an opaque identifier of type C{unicode}.
2608+- @type groups: C{set}
2609++ represented by an opaque identifier of type L{str}.
2610++ @type groups: L{set}
2611+ @ivar approved: Signals pre-approved subscription.
2612+- @type approved: C{bool}
2613++ @type approved: L{bool}
2614+ @ivar remove: Signals roster item removal.
2615+- @type remove: C{bool}
2616++ @type remove: L{bool}
2617+ """
2618+2619+ __subscriptionStates = {(False, False): None,
2620+@@ -755,7 +754,7 @@ class RosterItem(object):
2621+ item.approved = element.getAttribute('approved') in ('true', '1')
2622+ for subElement in domish.generateElementsQNamed(element.children,
2623+ 'group', NS_ROSTER):
2624+- item.groups.add(unicode(subElement))
2625++ item.groups.add(str(subElement))
2626+ return item
2627+2628+2629+@@ -771,7 +770,7 @@ class RosterRequest(Request):
2630+ retrieving the roster as a delta from a known cached version. This
2631+ should only be set if the recipient is known to support roster
2632+ versioning.
2633+- @type version: C{unicode}
2634++ @type version: L{str}
2635+2636+ @ivar rosterSet: If set, this is a roster set request. This flag is used
2637+ to make sure some attributes of the roster item are not rendered by
2638+@@ -821,7 +820,7 @@ class Roster(dict):
2639+ identifier for this version of the roster.
2640+2641+ @ivar version: Roster version identifier.
2642+- @type version: C{unicode}.
2643++ @type version: L{str}.
2644+ """
2645+2646+ version = None
2647+@@ -892,7 +891,7 @@ class RosterClientProtocol(XMPPHandler, IQHandlerMixin):
2648+ known to support roster versioning. If there is no (valid) cached
2649+ version of the roster, but roster versioning is desired,
2650+ C{version} should be set to the empty string (C{u''}).
2651+- @type version: C{unicode}
2652++ @type version: L{str}
2653+2654+ @return: Roster as a mapping from L{JID} to L{RosterItem}.
2655+ @rtype: L{twisted.internet.defer.Deferred}
2656+@@ -1023,11 +1022,11 @@ class Message(Stanza):
2657+2658+2659+ def _childParser_body(self, element):
2660+- self.body = unicode(element)
2661++ self.body = str(element)
2662+2663+2664+ def _childParser_subject(self, element):
2665+- self.subject = unicode(element)
2666++ self.subject = str(element)
2667+2668+2669+ def toElement(self):
2670+--
2671+2.44.1
···3334 ]
35 ++ lib.optionals (stdenv.buildPlatform.config != stdenv.hostPlatform.config) [
00000000036 # ./configure: sysdep posixspawnearlyreturn cannot be autodetected
37 # when cross-compiling. Please manually provide a value with the
38 # --with-sysdep-posixspawnearlyreturn=yes|no|... option.
···3334 ]
35 ++ lib.optionals (stdenv.buildPlatform.config != stdenv.hostPlatform.config) [
36+ # There's a fallback path for BSDs.
37+ "--with-sysdep-procselfexe=${
38+ if stdenv.hostPlatform.isLinux then
39+ "/proc/self/exe"
40+ else if stdenv.hostPlatform.isSunOS then
41+ "/proc/self/path/a.out"
42+ else
43+ "none"
44+ }"
45 # ./configure: sysdep posixspawnearlyreturn cannot be autodetected
46 # when cross-compiling. Please manually provide a value with the
47 # --with-sysdep-posixspawnearlyreturn=yes|no|... option.
+1
pkgs/top-level/aliases.nix
···773 svn_all_fast_export = svn-all-fast-export;
774 topGit = top-git;
775 }; # Added 2021-01-14
0776 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
777 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
778 gkraken = throw "'gkraken' has been deprecated by upstream. Consider using the replacement 'coolercontrol' instead."; # Added 2024-11-22
···773 svn_all_fast_export = svn-all-fast-export;
774 topGit = top-git;
775 }; # Added 2021-01-14
776+ github-copilot-cli = throw "'github-copilot-cli' has been removed because GitHub has replaced it with 'gh-copilot'."; # Added 2025-06-01
777 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
778 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
779 gkraken = throw "'gkraken' has been deprecated by upstream. Consider using the replacement 'coolercontrol' instead."; # Added 2024-11-22