Merge remote-tracking branch 'origin/master' into 3336.py36-off-travis

This commit is contained in:
Jean-Paul Calderone 2020-08-10 09:13:01 -04:00
commit f4e1062aa4
No known key found for this signature in database
GPG Key ID: 86E6F8BAE797C287
62 changed files with 398 additions and 232 deletions

View File

@ -24,6 +24,33 @@ allmydata.test.test_base62.Base62.test_known_values
allmydata.test.test_base62.Base62.test_num_octets_that_encode_to_this_many_chars
allmydata.test.test_base62.Base62.test_odd_sizes
allmydata.test.test_base62.Base62.test_roundtrip
allmydata.test.test_crypto.TestEd25519.test_deserialize_private_not_bytes
allmydata.test.test_crypto.TestEd25519.test_deserialize_public_not_bytes
allmydata.test.test_crypto.TestEd25519.test_key_serialization
allmydata.test.test_crypto.TestEd25519.test_sign_invalid_pubkey
allmydata.test.test_crypto.TestEd25519.test_signature_data_not_bytes
allmydata.test.test_crypto.TestEd25519.test_signature_not_bytes
allmydata.test.test_crypto.TestEd25519.test_signed_data_not_bytes
allmydata.test.test_crypto.TestEd25519.test_verify_invalid_pubkey
allmydata.test.test_crypto.TestRegression.test_aes_no_iv_process_long_input
allmydata.test.test_crypto.TestRegression.test_aes_no_iv_process_short_input
allmydata.test.test_crypto.TestRegression.test_aes_with_iv_process_long_input
allmydata.test.test_crypto.TestRegression.test_aes_with_iv_process_short_input
allmydata.test.test_crypto.TestRegression.test_decode_ed15519_keypair
allmydata.test.test_crypto.TestRegression.test_decode_rsa_keypair
allmydata.test.test_crypto.TestRegression.test_encrypt_data_not_bytes
allmydata.test.test_crypto.TestRegression.test_incorrect_iv_size
allmydata.test.test_crypto.TestRegression.test_iv_not_bytes
allmydata.test.test_crypto.TestRegression.test_key_incorrect_size
allmydata.test.test_crypto.TestRegression.test_old_start_up_test
allmydata.test.test_crypto.TestRsa.test_keys
allmydata.test.test_crypto.TestRsa.test_sign_invalid_pubkey
allmydata.test.test_crypto.TestRsa.test_verify_invalid_pubkey
allmydata.test.test_crypto.TestUtil.test_remove_prefix_bad
allmydata.test.test_crypto.TestUtil.test_remove_prefix_entire_string
allmydata.test.test_crypto.TestUtil.test_remove_prefix_good
allmydata.test.test_crypto.TestUtil.test_remove_prefix_partial
allmydata.test.test_crypto.TestUtil.test_remove_prefix_zero
allmydata.test.test_deferredutil.DeferredUtilTests.test_failure
allmydata.test.test_deferredutil.DeferredUtilTests.test_gather_results
allmydata.test.test_deferredutil.DeferredUtilTests.test_success
@ -46,6 +73,8 @@ allmydata.test.test_hashutil.HashUtilTests.test_sha256d
allmydata.test.test_hashutil.HashUtilTests.test_sha256d_truncated
allmydata.test.test_hashutil.HashUtilTests.test_timing_safe_compare
allmydata.test.test_humanreadable.HumanReadable.test_repr
allmydata.test.test_iputil.GcUtil.test_gc_after_allocations
allmydata.test.test_iputil.GcUtil.test_release_delays_gc
allmydata.test.test_iputil.ListAddresses.test_get_local_ip_for
allmydata.test.test_iputil.ListAddresses.test_list_async
allmydata.test.test_iputil.ListAddresses.test_list_async_mock_cygwin
@ -54,6 +83,14 @@ allmydata.test.test_iputil.ListAddresses.test_list_async_mock_ip_addr
allmydata.test.test_iputil.ListAddresses.test_list_async_mock_route
allmydata.test.test_iputil.ListenOnUsed.test_random_port
allmydata.test.test_iputil.ListenOnUsed.test_specific_port
allmydata.test.test_log.Log.test_default_facility
allmydata.test.test_log.Log.test_err
allmydata.test.test_log.Log.test_grandparent_id
allmydata.test.test_log.Log.test_no_prefix
allmydata.test.test_log.Log.test_numming
allmydata.test.test_log.Log.test_parent_id
allmydata.test.test_log.Log.test_with_bytes_prefix
allmydata.test.test_log.Log.test_with_prefix
allmydata.test.test_netstring.Netstring.test_encode
allmydata.test.test_netstring.Netstring.test_extra
allmydata.test.test_netstring.Netstring.test_nested

0
newsfragments/3326.minor Normal file
View File

0
newsfragments/3361.minor Normal file
View File

0
newsfragments/3364.minor Normal file
View File

0
newsfragments/3365.minor Normal file
View File

0
newsfragments/3366.minor Normal file
View File

0
newsfragments/3368.minor Normal file
View File

0
newsfragments/3372.minor Normal file
View File

View File

@ -7,6 +7,8 @@ bdist_egg = update_version bdist_egg
bdist_wheel = update_version bdist_wheel
[flake8]
# For now, only use pyflakes errors; flake8 is still helpful because it allows
# ignoring specific errors/warnings when needed.
select = F
# Enforce all pyflakes constraints, and also prohibit tabs for indentation.
# Reference:
# https://flake8.pycqa.org/en/latest/user/error-codes.html
# https://pycodestyle.pycqa.org/en/latest/intro.html#error-codes
select = F, W191

View File

@ -5,4 +5,15 @@ For the most part, these functions use and return objects that are
documented in the `cryptography` library -- however, code inside Tahoe
should only use these functions and not rely on features of any
objects that `cryptography` documents.
Ported to Python 3.
"""
from __future__ import unicode_literals
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401

View File

@ -6,7 +6,17 @@ These functions use and return objects that are documented in the
`cryptography` library -- however, code inside Tahoe should only use
functions from allmydata.crypto.aes and not rely on features of any
objects that `cryptography` documents.
Ported to Python 3.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
import six

View File

@ -13,7 +13,18 @@ cut-and-pasteability. The base62 encoding is shorter than the base32 form,
but the minor usability improvement is not worth the documentation and
specification confusion of using a non-standard encoding. So we stick with
base32.
Ported to Python 3.
'''
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
import six

View File

@ -1,6 +1,16 @@
"""
Exceptions raise by allmydata.crypto.* modules
Ported to Python 3.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
class BadSignature(Exception):

View File

@ -9,8 +9,17 @@ features of any objects that `cryptography` documents.
That is, the public and private keys are opaque objects; DO NOT depend
on any of their methods.
"""
Ported to Python 3.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.backends import default_backend

View File

@ -1,6 +1,16 @@
"""
Utilities used by allmydata.crypto modules
Ported to Python 3.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from allmydata.crypto.error import BadPrefixError

View File

@ -45,6 +45,8 @@ Written by Connelly Barnes in 2005 and released into the
public domain with no warranty of any kind, either expressed
or implied. It probably won't make your computer catch on fire,
or eat your children, but it might. Use at your own risk.
Ported to Python 3.
"""
from __future__ import absolute_import
@ -54,7 +56,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from allmydata.util import mathutil # from the pyutil library

View File

@ -11,7 +11,7 @@ from __future__ import print_function
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
import os
import time

View File

@ -10,7 +10,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from datetime import timedelta

View File

@ -10,7 +10,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
import base64

View File

@ -11,7 +11,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from past.builtins import chr as byteschr

View File

@ -1,4 +1,14 @@
import six
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from future.utils import native_bytes
import unittest
from base64 import b64decode
@ -37,17 +47,18 @@ class TestRegression(unittest.TestCase):
# priv = rsa.generate(2048)
# priv_str = b64encode(priv.serialize())
# pub_str = b64encode(priv.get_verifying_key().serialize())
RSA_2048_PRIV_KEY = six.b(b64decode(f.read().strip()))
RSA_2048_PRIV_KEY = b64decode(f.read().strip())
assert isinstance(RSA_2048_PRIV_KEY, native_bytes)
with RESOURCE_DIR.child('pycryptopp-rsa-2048-sig.txt').open('r') as f:
# Signature created using `RSA_2048_PRIV_KEY` via:
#
# sig = priv.sign(b'test')
RSA_2048_SIG = six.b(b64decode(f.read().strip()))
RSA_2048_SIG = b64decode(f.read().strip())
with RESOURCE_DIR.child('pycryptopp-rsa-2048-pub.txt').open('r') as f:
# The public key corresponding to `RSA_2048_PRIV_KEY`.
RSA_2048_PUB_KEY = six.b(b64decode(f.read().strip()))
RSA_2048_PUB_KEY = b64decode(f.read().strip())
def test_old_start_up_test(self):
"""
@ -283,7 +294,7 @@ class TestEd25519(unittest.TestCase):
private_key, public_key = ed25519.create_signing_keypair()
private_key_str = ed25519.string_from_signing_key(private_key)
self.assertIsInstance(private_key_str, six.string_types)
self.assertIsInstance(private_key_str, native_bytes)
private_key2, public_key2 = ed25519.signing_keypair_from_string(private_key_str)
@ -299,7 +310,7 @@ class TestEd25519(unittest.TestCase):
# ditto, but for the verifying keys
public_key_str = ed25519.string_from_verifying_key(public_key)
self.assertIsInstance(public_key_str, six.string_types)
self.assertIsInstance(public_key_str, native_bytes)
public_key2 = ed25519.verifying_key_from_string(public_key_str)
self.assertEqual(
@ -403,7 +414,7 @@ class TestRsa(unittest.TestCase):
priv_key, pub_key = rsa.create_signing_keypair(2048)
priv_key_str = rsa.der_string_from_signing_key(priv_key)
self.assertIsInstance(priv_key_str, six.string_types)
self.assertIsInstance(priv_key_str, native_bytes)
priv_key2, pub_key2 = rsa.create_signing_keypair_from_string(priv_key_str)

View File

@ -11,7 +11,7 @@ from __future__ import print_function
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from twisted.trial import unittest
from twisted.internet import defer, reactor

View File

@ -10,7 +10,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from twisted.trial import unittest

View File

@ -11,7 +11,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from twisted.trial import unittest

View File

@ -10,7 +10,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from twisted.trial import unittest

View File

@ -11,7 +11,7 @@ from __future__ import print_function
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from past.builtins import long

View File

@ -11,9 +11,10 @@ from __future__ import unicode_literals
from future.utils import PY2, native_str
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
import re, errno, subprocess, os, socket
import gc
from twisted.trial import unittest
@ -21,7 +22,7 @@ from tenacity import retry, stop_after_attempt
from foolscap.api import Tub
from allmydata.util import iputil
from allmydata.util import iputil, gcutil
import allmydata.test.common_py3 as testutil
from allmydata.util.namespace import Namespace
@ -228,3 +229,35 @@ class ListenOnUsed(unittest.TestCase):
s.close()
port2 = iputil.listenOnUnused(tub, port)
self.assertEqual(port, port2)
class GcUtil(unittest.TestCase):
"""Tests for allmydata.util.gcutil, which is used only by listenOnUnused."""
def test_gc_after_allocations(self):
"""The resource tracker triggers allocations every 26 allocations."""
tracker = gcutil._ResourceTracker()
collections = []
self.patch(gc, "collect", lambda: collections.append(1))
for _ in range(2):
for _ in range(25):
tracker.allocate()
self.assertEqual(len(collections), 0)
tracker.allocate()
self.assertEqual(len(collections), 1)
del collections[:]
def test_release_delays_gc(self):
"""Releasing a file descriptor resource delays GC collection."""
tracker = gcutil._ResourceTracker()
collections = []
self.patch(gc, "collect", lambda: collections.append(1))
for _ in range(2):
tracker.allocate()
for _ in range(3):
tracker.release()
for _ in range(25):
tracker.allocate()
self.assertEqual(len(collections), 0)
tracker.allocate()
self.assertEqual(len(collections), 1)

View File

@ -0,0 +1,156 @@
"""
Tests for allmydata.util.log.
Ported to Python 3.
"""
from __future__ import unicode_literals
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from twisted.trial import unittest
from twisted.python.failure import Failure
from foolscap.logging import log
from allmydata.util import log as tahoe_log
class SampleError(Exception):
pass
class Log(unittest.TestCase):
def setUp(self):
self.messages = []
def msg(msg, facility, parent, *args, **kwargs):
self.messages.append((msg, facility, parent, args, kwargs))
return "msg{}".format(len(self.messages))
self.patch(log, "msg", msg)
def test_err(self):
"""Logging with log.err() causes tests to fail."""
try:
raise SampleError("simple sample")
except:
f = Failure()
tahoe_log.err(format="intentional sample error",
failure=f, level=tahoe_log.OPERATIONAL, umid="wO9UoQ")
result = self.flushLoggedErrors(SampleError)
self.assertEqual(len(result), 1)
def test_default_facility(self):
"""
If facility is passed to PrefixingLogMixin.__init__, it is used as
default facility.
"""
class LoggingObject1(tahoe_log.PrefixingLogMixin):
pass
obj = LoggingObject1(facility="defaultfac")
obj.log("hello")
obj.log("world", facility="override")
self.assertEqual(self.messages[-2][1], "defaultfac")
self.assertEqual(self.messages[-1][1], "override")
def test_with_prefix(self):
"""
If prefix is passed to PrefixingLogMixin.__init__, it is used in
message rendering.
"""
class LoggingObject4(tahoe_log.PrefixingLogMixin):
pass
obj = LoggingObject4("fac", prefix="pre1")
obj.log("hello")
obj.log("world")
self.assertEqual(self.messages[-2][0], '<LoggingObject4 #1>(pre1): hello')
self.assertEqual(self.messages[-1][0], '<LoggingObject4 #1>(pre1): world')
def test_with_bytes_prefix(self):
"""
If bytes prefix is passed to PrefixingLogMixin.__init__, it is used in
message rendering.
"""
class LoggingObject5(tahoe_log.PrefixingLogMixin):
pass
obj = LoggingObject5("fac", prefix=b"pre1")
obj.log("hello")
obj.log("world")
self.assertEqual(self.messages[-2][0], '<LoggingObject5 #1>(pre1): hello')
self.assertEqual(self.messages[-1][0], '<LoggingObject5 #1>(pre1): world')
def test_no_prefix(self):
"""
If no prefix is passed to PrefixingLogMixin.__init__, it is not used in
message rendering.
"""
class LoggingObject2(tahoe_log.PrefixingLogMixin):
pass
obj = LoggingObject2()
obj.log("hello")
obj.log("world")
self.assertEqual(self.messages[-2][0], '<LoggingObject2 #1>: hello')
self.assertEqual(self.messages[-1][0], '<LoggingObject2 #1>: world')
def test_numming(self):
"""
Objects inheriting from PrefixingLogMixin get a unique number from a
class-specific counter.
"""
class LoggingObject3(tahoe_log.PrefixingLogMixin):
pass
obj = LoggingObject3()
obj2 = LoggingObject3()
obj.log("hello")
obj2.log("world")
self.assertEqual(self.messages[-2][0], '<LoggingObject3 #1>: hello')
self.assertEqual(self.messages[-1][0], '<LoggingObject3 #2>: world')
def test_parent_id(self):
"""
The parent message id can be passed in, otherwise the first message's
id is used as the parent.
This logic is pretty bogus, but that's what the code does.
"""
class LoggingObject1(tahoe_log.PrefixingLogMixin):
pass
obj = LoggingObject1()
result = obj.log("zero")
self.assertEqual(result, "msg1")
obj.log("one", parent="par1")
obj.log("two", parent="par2")
obj.log("three")
obj.log("four")
self.assertEqual([m[2] for m in self.messages],
[None, "par1", "par2", "msg1", "msg1"])
def test_grandparent_id(self):
"""
If grandparent message id is given, it's used as parent id of the first
message.
"""
class LoggingObject1(tahoe_log.PrefixingLogMixin):
pass
obj = LoggingObject1(grandparentmsgid="grand")
result = obj.log("zero")
self.assertEqual(result, "msg1")
obj.log("one", parent="par1")
obj.log("two", parent="par2")
obj.log("three")
obj.log("four")
self.assertEqual([m[2] for m in self.messages],
["grand", "par1", "par2", "msg1", "msg1"])

View File

@ -10,7 +10,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from twisted.trial import unittest

View File

@ -11,7 +11,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from twisted.trial import unittest
from twisted.internet import defer, reactor

View File

@ -10,7 +10,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
import gc

View File

@ -10,7 +10,7 @@ from __future__ import print_function
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from twisted.python.modules import (
getModule,

View File

@ -9,7 +9,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from past.builtins import long

View File

@ -10,7 +10,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from six.moves import StringIO # native string StringIO

View File

@ -8,7 +8,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from past.builtins import long

View File

@ -5,14 +5,11 @@ import os, time, sys
import yaml
from twisted.trial import unittest
from twisted.internet import defer, reactor
from twisted.python.failure import Failure
from allmydata.util import idlib, mathutil
from allmydata.util import fileutil
from allmydata.util import limiter, pollmixin
from allmydata.util import pollmixin
from allmydata.util import yamlutil
from allmydata.util import log as tahoe_log
from allmydata.util.fileutil import EncryptedTemporaryFile
from allmydata.test.common_util import ReallyEqualMixin
@ -429,81 +426,6 @@ class PollMixinTests(unittest.TestCase):
return d
class Limiter(unittest.TestCase):
def job(self, i, foo):
self.calls.append( (i, foo) )
self.simultaneous += 1
self.peak_simultaneous = max(self.simultaneous, self.peak_simultaneous)
d = defer.Deferred()
def _done():
self.simultaneous -= 1
d.callback("done %d" % i)
reactor.callLater(1.0, _done)
return d
def bad_job(self, i, foo):
raise ValueError("bad_job %d" % i)
def test_limiter(self):
self.calls = []
self.simultaneous = 0
self.peak_simultaneous = 0
l = limiter.ConcurrencyLimiter()
dl = []
for i in range(20):
dl.append(l.add(self.job, i, foo=str(i)))
d = defer.DeferredList(dl, fireOnOneErrback=True)
def _done(res):
self.failUnlessEqual(self.simultaneous, 0)
self.failUnless(self.peak_simultaneous <= 10)
self.failUnlessEqual(len(self.calls), 20)
for i in range(20):
self.failUnless( (i, str(i)) in self.calls)
d.addCallback(_done)
return d
def test_errors(self):
self.calls = []
self.simultaneous = 0
self.peak_simultaneous = 0
l = limiter.ConcurrencyLimiter()
dl = []
for i in range(20):
dl.append(l.add(self.job, i, foo=str(i)))
d2 = l.add(self.bad_job, 21, "21")
d = defer.DeferredList(dl, fireOnOneErrback=True)
def _most_done(res):
results = []
for (success, result) in res:
self.failUnlessEqual(success, True)
results.append(result)
results.sort()
expected_results = ["done %d" % i for i in range(20)]
expected_results.sort()
self.failUnlessEqual(results, expected_results)
self.failUnless(self.peak_simultaneous <= 10)
self.failUnlessEqual(len(self.calls), 20)
for i in range(20):
self.failUnless( (i, str(i)) in self.calls)
def _good(res):
self.fail("should have failed, not got %s" % (res,))
def _err(f):
f.trap(ValueError)
self.failUnless("bad_job 21" in str(f))
d2.addCallbacks(_good, _err)
return d2
d.addCallback(_most_done)
def _all_done(res):
self.failUnlessEqual(self.simultaneous, 0)
self.failUnless(self.peak_simultaneous <= 10)
self.failUnlessEqual(len(self.calls), 20)
for i in range(20):
self.failUnless( (i, str(i)) in self.calls)
d.addCallback(_all_done)
return d
ctr = [0]
class EqButNotIs(object):
def __init__(self, x):
@ -528,20 +450,6 @@ class EqButNotIs(object):
return self.x == other
class SampleError(Exception):
pass
class Log(unittest.TestCase):
def test_err(self):
try:
raise SampleError("simple sample")
except:
f = Failure()
tahoe_log.err(format="intentional sample error",
failure=f, level=tahoe_log.OPERATIONAL, umid="wO9UoQ")
self.flushLoggedErrors(SampleError)
class YAML(unittest.TestCase):
def test_convert(self):
data = yaml.safe_dump(["str", u"unicode", u"\u1234nicode"])

View File

@ -10,7 +10,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
import sys
import pkg_resources

View File

@ -11,43 +11,53 @@ from __future__ import print_function
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
# Keep these sorted alphabetically, to reduce merge conflicts:
PORTED_MODULES = [
"allmydata.crypto",
"allmydata.crypto.aes",
"allmydata.crypto.ed25519",
"allmydata.crypto.error",
"allmydata.crypto.rsa",
"allmydata.crypto.util",
"allmydata.hashtree",
"allmydata.test.common_py3",
"allmydata.util._python3",
"allmydata.util.abbreviate",
"allmydata.util.assertutil",
"allmydata.util.base32",
"allmydata.util.base62",
"allmydata.util.deferredutil",
"allmydata.util.dictutil",
"allmydata.util.gcutil",
"allmydata.util.hashutil",
"allmydata.util.humanreadable",
"allmydata.util.iputil",
"allmydata.util.log",
"allmydata.util.mathutil",
"allmydata.util.namespace",
"allmydata.util.netstring",
"allmydata.util.observer",
"allmydata.util.pipeline",
"allmydata.util.pollmixin",
"allmydata.util._python3",
"allmydata.util.spans",
"allmydata.util.statistics",
"allmydata.util.time_format",
"allmydata.test.common_py3",
]
PORTED_TEST_MODULES = [
"allmydata.test.test_abbreviate",
"allmydata.test.test_base32",
"allmydata.test.test_base62",
"allmydata.test.test_crypto",
"allmydata.test.test_deferredutil",
"allmydata.test.test_dictutil",
"allmydata.test.test_hashtree",
"allmydata.test.test_hashutil",
"allmydata.test.test_humanreadable",
"allmydata.test.test_iputil",
"allmydata.test.test_log",
"allmydata.test.test_netstring",
"allmydata.test.test_observer",
"allmydata.test.test_pipeline",

View File

@ -10,7 +10,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
import re
from datetime import timedelta

View File

@ -14,7 +14,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
# The API importers expect:

View File

@ -10,7 +10,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
if PY2:
def backwardscompat_bytes(b):

View File

@ -10,7 +10,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
if PY2:
import string

View File

@ -11,7 +11,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
import time

View File

@ -13,7 +13,7 @@ if PY2:
# IMPORTANT: We deliberately don't import dict. The issue is that we're
# subclassing dict, so we'd end up exposing Python 3 dict APIs to lots of
# code that doesn't support it.
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, list, object, range, str, max, min # noqa: F401
class DictOfSets(dict):

View File

@ -7,7 +7,17 @@ Helpers for managing garbage collection.
a result. Register allocation and release of *bare* file descriptors with
this object (file objects, socket objects, etc, have their own integration
with the garbage collector and don't need to bother with this).
Ported to Python 3.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
__all__ = [
"fileDescriptorResource",

View File

@ -10,7 +10,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from past.builtins import chr as byteschr

View File

@ -11,7 +11,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
import os
from reprlib import Repr

View File

@ -11,7 +11,7 @@ from __future__ import unicode_literals
from future.utils import PY2, native_str
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
import os, re, socket, subprocess, errno
from sys import platform

View File

@ -1,40 +0,0 @@
from twisted.internet import defer
from foolscap.api import eventually
class ConcurrencyLimiter(object):
"""I implement a basic concurrency limiter. Add work to it in the form of
(callable, args, kwargs) tuples. No more than LIMIT callables will be
outstanding at any one time.
"""
def __init__(self, limit=10):
self.limit = limit
self.pending = []
self.active = 0
def __repr__(self):
return "<Limiter with %d/%d/%d>" % (self.active, len(self.pending),
self.limit)
def add(self, cb, *args, **kwargs):
d = defer.Deferred()
task = (cb, args, kwargs, d)
self.pending.append(task)
self.maybe_start_task()
return d
def maybe_start_task(self):
if self.active >= self.limit:
return
if not self.pending:
return
(cb, args, kwargs, done_d) = self.pending.pop(0)
self.active += 1
d = defer.maybeDeferred(cb, *args, **kwargs)
d.addBoth(self._done, done_d)
def _done(self, res, done_d):
self.active -= 1
eventually(done_d.callback, res)
eventually(self.maybe_start_task)

View File

@ -1,4 +1,18 @@
from allmydata.util import nummedobj
"""
Logging utilities.
Ported to Python 3.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from pyutil import nummedobj
from foolscap.logging import log
from twisted.python import log as tw_log
@ -36,8 +50,8 @@ class LogMixin(object):
def log(self, msg, facility=None, parent=None, *args, **kwargs):
if facility is None:
facility = self._facility
pmsgid = None
if parent is None:
pmsgid = parent
if pmsgid is None:
pmsgid = self._parentmsgid
if pmsgid is None:
pmsgid = self._grandparentmsgid
@ -54,6 +68,8 @@ class PrefixingLogMixin(nummedobj.NummedObj, LogMixin):
LogMixin.__init__(self, facility, grandparentmsgid)
if prefix:
if isinstance(prefix, bytes):
prefix = prefix.decode("utf-8", errors="replace")
self._prefix = "%s(%s): " % (self.__repr__(), prefix)
else:
self._prefix = "%s: " % (self.__repr__(),)

View File

@ -13,7 +13,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
# The API importers expect:

View File

@ -10,7 +10,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from past.builtins import long

View File

@ -1,42 +0,0 @@
import collections, itertools, functools
objnums = collections.defaultdict(itertools.count)
@functools.total_ordering
class NummedObj(object):
"""
This is useful for nicer debug printouts. Instead of objects of the same class being
distinguished from one another by their memory address, they each get a unique number, which
can be read as "the first object of this class", "the second object of this class", etc. This
is especially useful because separate runs of a program will yield identical debug output,
(assuming that the objects get created in the same order in each run). This makes it possible
to diff outputs from separate runs to see what changed, without having to ignore a difference
on every line due to different memory addresses of objects.
"""
def __init__(self, klass=None):
"""
@param klass: in which class are you counted? If default value of `None', then self.__class__ will be used.
"""
if klass is None:
klass = self.__class__
self._classname = klass.__name__
self._objid = objnums[self._classname].next()
def __repr__(self):
return "<%s #%d>" % (self._classname, self._objid,)
def __lt__(self, other):
if isinstance(other, NummedObj):
return (self._objid, self._classname,) < (other._objid, other._classname,)
return NotImplemented
def __eq__(self, other):
if isinstance(other, NummedObj):
return (self._objid, self._classname,) == (other._objid, other._classname,)
return NotImplemented
def __hash__(self):
return id(self)

View File

@ -11,7 +11,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
import weakref
from twisted.internet import defer

View File

@ -11,7 +11,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from twisted.internet import defer
from twisted.python.failure import Failure

View File

@ -11,7 +11,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
import time
from twisted.internet import task

View File

@ -5,7 +5,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
class Spans(object):

View File

@ -18,7 +18,7 @@ from __future__ import print_function
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from functools import reduce

View File

@ -11,7 +11,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
from future.utils import native_str
import calendar, datetime, re, time

View File

@ -11,7 +11,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
import re

View File

@ -11,7 +11,7 @@ from __future__ import unicode_literals
from future.utils import PY2
if PY2:
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, int, list, object, range, str, max, min # noqa: F401
from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, str, max, min # noqa: F401
__all__ = [
"PackagingError",

View File

@ -49,7 +49,7 @@ commands =
tahoe --version
[testenv:py36]
# git inside of ratchet.sh needs $HOME.
# On macOS, git inside of ratchet.sh needs $HOME.
passenv = {[testenv]passenv} HOME
commands = {toxinidir}/misc/python3/ratchet.sh
@ -77,6 +77,8 @@ commands =
coverage xml
[testenv:codechecks]
# On macOS, git inside of towncrier needs $HOME.
passenv = HOME
whitelist_externals =
/bin/mv
commands =