Skip to content

Commit

Permalink
Merge branch '8079-no-gmpy' of github.com:twisted/twisted into 8079-n…
Browse files Browse the repository at this point in the history
…o-gmpy
  • Loading branch information
hawkowl committed Sep 16, 2016
2 parents 5d9b2e6 + fc2faa4 commit df1589b
Show file tree
Hide file tree
Showing 22 changed files with 1,260 additions and 1,557 deletions.
6 changes: 4 additions & 2 deletions docs/core/development/policy/coding-standard.rst
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,6 @@ In case of local names conflicts due to import, use the ``as`` syntax, for examp
The encoding must always be ASCII, so no coding cookie is necessary.

Python 3 compatible modules must be listed in the relevant sections of ``twisted.python.dist3``.


Packages
--------
Expand Down Expand Up @@ -612,6 +610,10 @@ Python 3
Twisted is being ported to Python 3, targeting Python 3.3+.
Please see :doc:`Porting to Python 3 </core/howto/python3>` for details.

All new modules must be Python 2.7 & 3.3+ compatible, and all new code to ported modules must be Python 2.7 & 3.3+ compatible.
New code in non-ported modules must be written in a 2.7 & 3.3+ compatible way (explicit bytes/unicode strings, new exception raising format, etc) as to prevent extra work when that module is eventually ported.
Code targeting Python 3 specific features must gracefully fall-back on Python 2 as much as is reasonably possible (for example, Python 2 support for 'async/await' is not reasonably possible and would not be required, but code that uses a Python 3-specific module such as ipaddress should be able to use a backport to 2.7 if available).


Database
--------
Expand Down
50 changes: 18 additions & 32 deletions docs/core/howto/python3.rst
Original file line number Diff line number Diff line change
@@ -1,64 +1,53 @@

:LastChangedDate: $LastChangedDate$
:LastChangedRevision: $LastChangedRevision$
:LastChangedBy: $LastChangedBy$

Porting to Python 3
===================






Introduction
------------

Twisted is currently being ported to work with Python 3.3. This
document covers Twisted-specific issues in porting your code to Python
3.
Twisted is currently being ported to work with Python 3.3+.
This document covers Twisted-specific issues in porting your code to Python 3.

Only some parts of Twisted have been ported, and therefore only a subset of modules are installed under Python 3.
You can see the full list of ported modules in :api:`twisted.python.dist3 <twisted.python.dist3>`.
Most, but not all, of Twisted has been ported, and therefore only a subset of modules are installed under Python 3.
You can see the remaining modules that need to be ported at :api:`twisted.python._dist3 <twisted.python._dist3>`, if it is not listed there, then most of all of that module will be ported.


API Differences
---------------




twisted.python.failure
~~~~~~~~~~~~~~~~~~~~~~


:api:`twisted.python.failure.Failure.trap <Failure.trap>`

:api:`twisted.python.failure.Failure.trap <Failure.trap>`
raises itself (i.e. a :api:`twisted.python.failure.Failure <Failure>` ) in Python 2. In Python 3,
the wrapped exception will be re-raised.





Byte Strings and Text Strings
-----------------------------



Several APIs which on Python 2 accepted or produced byte strings
(instances of ``str`` , sometimes just called *bytes* ) have
changed to accept or produce text strings (instances of ``str`` ,
sometimes just called *text* or *unicode* ) on Python 3.




From ``twisted.internet.address`` , the ``IPv4Address``

From ``twisted.internet.address`` , the ``IPv4Address``
and ``IPv6Address`` classes have had two attributes change from
byte strings to text strings: ``type`` and ``host`` .




``twisted.python.log`` has shifted significantly towards text
Expand All @@ -67,14 +56,14 @@ call like ``msg("foo")`` , must now be text strings. Consequently,
on Python 3, event dictionaries passed to log observes will contain text
strings where they previously contained byte strings.




``twisted.python.runtime.platformType`` and the return value
from ``twisted.python.runtime.Platform.getType`` are now both text
strings.




``twisted.python.filepath.FilePath`` has *not* changed.
Expand All @@ -83,13 +72,13 @@ update their usage of ``FilePath`` , at least to pass explicit byte
string literals rather than "native" string literals (which are text on
Python 3).




``reactor.addSystemEventTrigger`` arguments that were
previously byte strings are now native strings.




``twisted.names.dns`` deals with strings with a wide range of
Expand All @@ -102,19 +91,16 @@ example, ``Record_A`` 's ``address`` parameter) is now a
text string. Additionally, time-to-live (ttl) values given as strings must
now be given as text strings.




``twisted.web.resource.IResource`` continues to deal with URLs
and all URL-derived values as byte strings.




``twisted.web.resource.ErrorPage`` has several string attributes
(``template`` , ``brief`` , and ``detail`` ) which
were previously byte strings. On Python 3 only, these must now be text
strings.



120 changes: 120 additions & 0 deletions src/twisted/mail/_cred.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.

"""
Credential managers for L{twisted.mail}.
"""

from __future__ import absolute_import, division

import hmac

from zope.interface import implementer

from twisted.cred import credentials
from twisted.python.compat import nativeString
from twisted.mail._except import IllegalClientResponse
from twisted.mail.interfaces import IClientAuthentication


@implementer(IClientAuthentication)
class CramMD5ClientAuthenticator:
def __init__(self, user):
self.user = user


def getName(self):
return b"CRAM-MD5"


def challengeResponse(self, secret, chal):
response = hmac.HMAC(secret, chal).hexdigest().encode('ascii')
return self.user + b' ' + response



@implementer(IClientAuthentication)
class LOGINAuthenticator:
def __init__(self, user):
self.user = user
self.challengeResponse = self.challengeUsername


def getName(self):
return b"LOGIN"


def challengeUsername(self, secret, chal):
# Respond to something like "Username:"
self.challengeResponse = self.challengeSecret
return self.user


def challengeSecret(self, secret, chal):
# Respond to something like "Password:"
return secret



@implementer(IClientAuthentication)
class PLAINAuthenticator:
def __init__(self, user):
self.user = user


def getName(self):
return b"PLAIN"


def challengeResponse(self, secret, chal):
return b'\0' + self.user + b'\0' + secret



class LOGINCredentials(credentials.UsernamePassword):
def __init__(self):
self.challenges = [b'Password\0', b'User Name\0']
self.responses = [b'password', b'username']
credentials.UsernamePassword.__init__(self, None, None)


def getChallenge(self):
return self.challenges.pop()


def setResponse(self, response):
setattr(self, nativeString(self.responses.pop()), response)


def moreChallenges(self):
return bool(self.challenges)



class PLAINCredentials(credentials.UsernamePassword):
def __init__(self):
credentials.UsernamePassword.__init__(self, None, None)


def getChallenge(self):
return b''


def setResponse(self, response):
parts = response.split(b'\0')
if len(parts) != 3:
raise IllegalClientResponse(
"Malformed Response - wrong number of parts")
useless, self.username, self.password = parts


def moreChallenges(self):
return False



__all__ = [
"CramMD5ClientAuthenticator",
"LOGINCredentials", "LOGINAuthenticator",
"PLAINCredentials", "PLAINAuthenticator",
]
Loading

0 comments on commit df1589b

Please sign in to comment.