Changeset 6e24def in trunk


Ignore:
Timestamp:
2020-08-13T19:53:02Z (5 years ago)
Author:
Itamar Turner-Trauring <itamar@…>
Branches:
master
Children:
af61571
Parents:
1037854 (diff), 942c5d52 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch '3376.encodingutil-python-3' into 3377.configutil-connection_status-python-3

Files:
5 added
2 deleted
22 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified .circleci/Dockerfile.centos

    r1037854 r6e24def  
    11ARG TAG
    22FROM centos:${TAG}
     3ARG PYTHON_VERSION
    34
    45ENV WHEELHOUSE_PATH /tmp/wheelhouse
     
    1213    sudo \
    1314    make automake gcc gcc-c++ \
    14     python2 \
    15     python2-devel \
     15    python${PYTHON_VERSION} \
     16    python${PYTHON_VERSION}-devel \
    1617    libffi-devel \
    1718    openssl-devel \
     
    2425COPY . ${BUILD_SRC_ROOT}
    2526
    26 RUN "${BUILD_SRC_ROOT}"/.circleci/prepare-image.sh "${WHEELHOUSE_PATH}" "${VIRTUALENV_PATH}" "${BUILD_SRC_ROOT}" "python2.7"
     27RUN "${BUILD_SRC_ROOT}"/.circleci/prepare-image.sh "${WHEELHOUSE_PATH}" "${VIRTUALENV_PATH}" "${BUILD_SRC_ROOT}" "python${PYTHON_VERSION}"
  • TabularUnified .circleci/Dockerfile.debian

    r1037854 r6e24def  
    11ARG TAG
    22FROM debian:${TAG}
     3ARG PYTHON_VERSION
    34
    45ENV WHEELHOUSE_PATH /tmp/wheelhouse
     
    910RUN apt-get --quiet update && \
    1011    apt-get --quiet --yes install \
    11         git \
    12         lsb-release \
     12        git \
     13        lsb-release \
    1314        sudo \
    14         build-essential \
    15         python2.7 \
    16         python2.7-dev \
    17         libffi-dev \
    18         libssl-dev \
    19         libyaml-dev \
    20         virtualenv
     15        build-essential \
     16        python${PYTHON_VERSION} \
     17        python${PYTHON_VERSION}-dev \
     18        libffi-dev \
     19        libssl-dev \
     20        libyaml-dev \
     21        virtualenv
    2122
    2223# Get the project source.  This is better than it seems.  CircleCI will
     
    2425COPY . ${BUILD_SRC_ROOT}
    2526
    26 RUN "${BUILD_SRC_ROOT}"/.circleci/prepare-image.sh "${WHEELHOUSE_PATH}" "${VIRTUALENV_PATH}" "${BUILD_SRC_ROOT}" "python2.7"
     27RUN "${BUILD_SRC_ROOT}"/.circleci/prepare-image.sh "${WHEELHOUSE_PATH}" "${VIRTUALENV_PATH}" "${BUILD_SRC_ROOT}" "python${PYTHON_VERSION}"
    2728
    2829# Only the integration tests currently need this but it doesn't hurt to always
  • TabularUnified .circleci/Dockerfile.fedora

    r1037854 r6e24def  
    11ARG TAG
    22FROM fedora:${TAG}
     3ARG PYTHON_VERSION
    34
    45ENV WHEELHOUSE_PATH /tmp/wheelhouse
     
    1213    sudo \
    1314    make automake gcc gcc-c++ \
    14     python \
    15     python-devel \
     15    python${PYTHON_VERSION} \
     16    python${PYTHON_VERSION}-devel \
    1617    libffi-devel \
    1718    openssl-devel \
     
    2425COPY . ${BUILD_SRC_ROOT}
    2526
    26 RUN "${BUILD_SRC_ROOT}"/.circleci/prepare-image.sh "${WHEELHOUSE_PATH}" "${VIRTUALENV_PATH}" "${BUILD_SRC_ROOT}" "python2.7"
     27RUN "${BUILD_SRC_ROOT}"/.circleci/prepare-image.sh "${WHEELHOUSE_PATH}" "${VIRTUALENV_PATH}" "${BUILD_SRC_ROOT}" "python${PYTHON_VERSION}"
  • TabularUnified .circleci/Dockerfile.ubuntu

    r1037854 r6e24def  
    11ARG TAG
    22FROM ubuntu:${TAG}
     3ARG PYTHON_VERSION
    34
    45ENV WHEELHOUSE_PATH /tmp/wheelhouse
     
    1415        sudo \
    1516        build-essential \
    16         python2.7 \
    17         python2.7-dev \
     17        python${PYTHON_VERSION} \
     18        python${PYTHON_VERSION}-dev \
    1819        libffi-dev \
    1920        libssl-dev \
     
    2728COPY . ${BUILD_SRC_ROOT}
    2829
    29 RUN "${BUILD_SRC_ROOT}"/.circleci/prepare-image.sh "${WHEELHOUSE_PATH}" "${VIRTUALENV_PATH}" "${BUILD_SRC_ROOT}" "python2.7"
     30RUN "${BUILD_SRC_ROOT}"/.circleci/prepare-image.sh "${WHEELHOUSE_PATH}" "${VIRTUALENV_PATH}" "${BUILD_SRC_ROOT}" "python${PYTHON_VERSION}"
  • TabularUnified .circleci/config.yml

    r1037854 r6e24def  
    2727      - "centos-8"
    2828
    29       - "slackware-14.2"
    30 
    3129      - "nixos-19.09"
    3230
    3331      # Test against PyPy 2.7
    3432      - "pypy2.7-buster"
     33
     34      # Just one Python 3.6 configuration while the port is in-progress.
     35      - "python3.6"
    3536
    3637      # Other assorted tasks and configurations
     
    7374      - "build-image-fedora-29"
    7475      - "build-image-centos-8"
    75       - "build-image-slackware-14.2"
    7676      - "build-image-pypy-2.7-buster"
     77      - "build-image-python36-ubuntu"
    7778
    7879
     
    122123  debian-9: &DEBIAN
    123124    docker:
    124       - image: "tahoelafsci/debian:9"
     125      - image: "tahoelafsci/debian:9-py2.7"
    125126        user: "nobody"
    126127
     
    199200    <<: *DEBIAN
    200201    docker:
    201       - image: "tahoelafsci/debian:8"
     202      - image: "tahoelafsci/debian:8-py2.7"
    202203        user: "nobody"
    203204
     
    206207    <<: *DEBIAN
    207208    docker:
    208       - image: "tahoelafsci/pypy:2.7-buster"
     209      - image: "tahoelafsci/pypy:buster-py2"
    209210        user: "nobody"
    210211
     
    262263    <<: *DEBIAN
    263264    docker:
    264       - image: "tahoelafsci/ubuntu:16.04"
    265         user: "nobody"
    266 
    267 
    268   ubuntu-18.04:
    269     <<: *DEBIAN
    270     docker:
    271       - image: "tahoelafsci/ubuntu:18.04"
    272         user: "nobody"
     265      - image: "tahoelafsci/ubuntu:16.04-py2.7"
     266        user: "nobody"
     267
     268
     269  ubuntu-18.04: &UBUNTU_18_04
     270    <<: *DEBIAN
     271    docker:
     272      - image: "tahoelafsci/ubuntu:18.04-py2.7"
     273        user: "nobody"
     274
     275
     276  python3.6:
     277    <<: *UBUNTU_18_04
     278    docker:
     279      - image: "tahoelafsci/ubuntu:18.04-py3"
     280        user: "nobody"
     281
     282    environment:
     283      <<: *UTF_8_ENVIRONMENT
     284      TAHOE_LAFS_TOX_ENVIRONMENT: "py36"
    273285
    274286
     
    282294  centos-8: &RHEL_DERIV
    283295    docker:
    284       - image: "tahoelafsci/centos:8"
     296      - image: "tahoelafsci/centos:8-py2"
    285297        user: "nobody"
    286298
     
    304316    <<: *RHEL_DERIV
    305317    docker:
    306       - image: "tahoelafsci/fedora:28"
     318      - image: "tahoelafsci/fedora:28-py"
    307319        user: "nobody"
    308320
     
    311323    <<: *RHEL_DERIV
    312324    docker:
    313       - image: "tahoelafsci/fedora:29"
    314         user: "nobody"
    315 
    316 
    317   slackware-14.2:
    318     docker:
    319       - image: "tahoelafsci/slackware:14.2"
    320         user: "nobody"
    321 
    322     environment: *UTF_8_ENVIRONMENT
    323 
    324     # pip cannot install packages if the working directory is not readable.
    325     # We want to run a lot of steps as nobody instead of as root.
    326     working_directory: "/tmp/project"
    327 
    328     steps:
    329       - "checkout"
    330       - run: *SETUP_VIRTUALENV
    331       - run: *RUN_TESTS
    332       - store_test_results: *STORE_TEST_RESULTS
    333       - store_artifacts: *STORE_TEST_LOG
    334       - store_artifacts: *STORE_OTHER_ARTIFACTS
    335       - run: *SUBMIT_COVERAGE
     325      - image: "tahoelafsci/fedora:29-py"
     326        user: "nobody"
     327
    336328
    337329  nixos-19.09:
     
    398390
    399391    environment:
    400       DISTRO: "tahoelafsci/<DISTRO>:foo"
    401       TAG: "tahoelafsci/distro:<TAG>"
     392      DISTRO: "tahoelafsci/<DISTRO>:foo-py2"
     393      TAG: "tahoelafsci/distro:<TAG>-py2"
     394      PYTHON_VERSION: "tahoelafsci/distro:tag-py<PYTHON_VERSION}"
    402395
    403396    steps:
     
    451444                build \
    452445                --build-arg TAG=${TAG} \
    453                 -t tahoelafsci/${DISTRO}:${TAG} \
     446                --build-arg PYTHON_VERSION=${PYTHON_VERSION} \
     447                -t tahoelafsci/${DISTRO}:${TAG}-py${PYTHON_VERSION} \
    454448                -f ~/project/.circleci/Dockerfile.${DISTRO} \
    455449                ~/project/
     
    457451          name: "Push image"
    458452          command: |
    459             docker push tahoelafsci/${DISTRO}:${TAG}
     453            docker push tahoelafsci/${DISTRO}:${TAG}-py${PYTHON_VERSION}
    460454
    461455
     
    466460      DISTRO: "debian"
    467461      TAG: "8"
     462      PYTHON_VERSION: "2.7"
    468463
    469464
     
    474469      DISTRO: "debian"
    475470      TAG: "9"
     471      PYTHON_VERSION: "2.7"
    476472
    477473
     
    482478      DISTRO: "ubuntu"
    483479      TAG: "16.04"
     480      PYTHON_VERSION: "2.7"
    484481
    485482
     
    490487      DISTRO: "ubuntu"
    491488      TAG: "18.04"
     489      PYTHON_VERSION: "2.7"
     490
     491
     492  build-image-python36-ubuntu:
     493    <<: *BUILD_IMAGE
     494
     495    environment:
     496      DISTRO: "ubuntu"
     497      TAG: "18.04"
     498      PYTHON_VERSION: "3"
    492499
    493500
     
    506513      DISTRO: "centos"
    507514      TAG: "8"
     515      PYTHON_VERSION: "2"
    508516
    509517
     
    514522      DISTRO: "fedora"
    515523      TAG: "28"
     524      # The default on Fedora (this version anyway) is still Python 2.
     525      PYTHON_VERSION: ""
    516526
    517527
     
    524534
    525535
    526   build-image-slackware-14.2:
    527     <<: *BUILD_IMAGE
    528 
    529     environment:
    530       DISTRO: "slackware"
    531       TAG: "14.2"
    532 
    533 
    534536  build-image-pypy-2.7-buster:
    535537    <<: *BUILD_IMAGE
     
    537539    environment:
    538540      DISTRO: "pypy"
    539       TAG: "2.7-buster"
     541      TAG: "buster"
     542      # We only have Python 2 for PyPy right now so there's no support for
     543      # setting up PyPy 3 in the image building toolchain.  This value is just
     544      # for constructing the right Docker image tag.
     545      PYTHON_VERSION: "2"
  • TabularUnified .circleci/populate-wheelhouse.sh

    r1037854 r6e24def  
    3737export PIP_FIND_LINKS="file://${WHEELHOUSE_PATH}"
    3838
    39 # Populate the wheelhouse, if necessary.
    40 "${PIP}" \
     39# Populate the wheelhouse, if necessary.  zfec 1.5.3 can only be built with a
     40# UTF-8 environment so make sure we have one, at least for this invocation.
     41LANG="en_US.UTF-8" "${PIP}" \
    4142    wheel \
    4243    --wheel-dir "${WHEELHOUSE_PATH}" \
  • TabularUnified .circleci/run-tests.sh

    r1037854 r6e24def  
    8282
    8383if [ -n "${ARTIFACTS}" ]; then
     84    if [ ! -e "${SUBUNIT2}" ]; then
     85        echo "subunitv2 output file does not exist: ${SUBUNIT2}"
     86        exit 1
     87    fi
     88
    8489    # Create a junitxml results area.
    8590    mkdir -p "$(dirname "${JUNITXML}")"
    86     ${BOOTSTRAP_VENV}/bin/subunit2junitxml < "${SUBUNIT2}" > "${JUNITXML}" || "${alternative}"
     91    # Always succeed even if subunit2junitxml fails.  subunit2junitxml signals
     92    # failure if the stream it is processing contains test failures.  This is
     93    # not what we care about.  If we cared about it, the test command above
     94    # would have signalled failure already and we wouldn't be here.
     95    "${BOOTSTRAP_VENV}"/bin/subunit2junitxml < "${SUBUNIT2}" > "${JUNITXML}" || true
    8796fi
  • TabularUnified misc/python3/ratchet-passing

    r1037854 r6e24def  
    1010allmydata.test.test_abbreviate.Abbreviate.test_space
    1111allmydata.test.test_abbreviate.Abbreviate.test_time
     12allmydata.test.test_backupdb.BackupDB.test_basic
     13allmydata.test.test_backupdb.BackupDB.test_upgrade_v1_v2
     14allmydata.test.test_backupdb.BackupDB.test_wrong_version
    1215allmydata.test.test_base32.Base32.test_a2b
    1316allmydata.test.test_base32.Base32.test_a2b_b2a_match_Pythons
     
    7174allmydata.test.test_dictutil.DictUtil.test_auxdict
    7275allmydata.test.test_dictutil.DictUtil.test_dict_of_sets
     76allmydata.test.test_encodingutil.EncodingUtilErrors.test_argv_to_unicode
     77allmydata.test.test_encodingutil.EncodingUtilErrors.test_get_io_encoding
     78allmydata.test.test_encodingutil.EncodingUtilErrors.test_get_io_encoding_not_from_stdout
     79allmydata.test.test_encodingutil.EncodingUtilErrors.test_no_unicode_normalization
     80allmydata.test.test_encodingutil.EncodingUtilErrors.test_unicode_to_output
     81allmydata.test.test_encodingutil.FilePaths.test_extend_filepath
     82allmydata.test.test_encodingutil.FilePaths.test_to_filepath
     83allmydata.test.test_encodingutil.FilePaths.test_unicode_from_filepath
     84allmydata.test.test_encodingutil.FilePaths.test_unicode_segments_from
     85allmydata.test.test_encodingutil.MacOSXLeopard.test_argv_to_unicode
     86allmydata.test.test_encodingutil.MacOSXLeopard.test_listdir_unicode
     87allmydata.test.test_encodingutil.MacOSXLeopard.test_unicode_platform_py3
     88allmydata.test.test_encodingutil.MacOSXLeopard.test_unicode_to_argv_py3
     89allmydata.test.test_encodingutil.MacOSXLeopard.test_unicode_to_output
     90allmydata.test.test_encodingutil.MacOSXLeopard.test_unicode_to_url
     91allmydata.test.test_encodingutil.MacOSXLeopard7bit.test_argv_to_unicode
     92allmydata.test.test_encodingutil.MacOSXLeopard7bit.test_listdir_unicode
     93allmydata.test.test_encodingutil.MacOSXLeopard7bit.test_unicode_platform_py3
     94allmydata.test.test_encodingutil.MacOSXLeopard7bit.test_unicode_to_argv_py3
     95allmydata.test.test_encodingutil.MacOSXLeopard7bit.test_unicode_to_output
     96allmydata.test.test_encodingutil.MacOSXLeopard7bit.test_unicode_to_url
     97allmydata.test.test_encodingutil.OpenBSD.test_argv_to_unicode
     98allmydata.test.test_encodingutil.OpenBSD.test_listdir_unicode
     99allmydata.test.test_encodingutil.OpenBSD.test_unicode_platform_py3
     100allmydata.test.test_encodingutil.OpenBSD.test_unicode_to_argv_py3
     101allmydata.test.test_encodingutil.OpenBSD.test_unicode_to_output
     102allmydata.test.test_encodingutil.OpenBSD.test_unicode_to_url
     103allmydata.test.test_encodingutil.QuoteOutput.test_quote_output_ascii
     104allmydata.test.test_encodingutil.QuoteOutput.test_quote_output_default
     105allmydata.test.test_encodingutil.QuoteOutput.test_quote_output_latin1
     106allmydata.test.test_encodingutil.QuoteOutput.test_quote_output_utf8
     107allmydata.test.test_encodingutil.QuotePaths.test_quote_filepath
     108allmydata.test.test_encodingutil.QuotePaths.test_quote_path
     109allmydata.test.test_encodingutil.StdlibUnicode.test_mkdir_open_exists_abspath_listdir_expanduser
     110allmydata.test.test_encodingutil.TestToFromStr.test_from_utf8_or_none
     111allmydata.test.test_encodingutil.TestToFromStr.test_to_str
     112allmydata.test.test_encodingutil.UbuntuKarmicLatin1.test_argv_to_unicode
     113allmydata.test.test_encodingutil.UbuntuKarmicLatin1.test_listdir_unicode
     114allmydata.test.test_encodingutil.UbuntuKarmicLatin1.test_unicode_platform_py3
     115allmydata.test.test_encodingutil.UbuntuKarmicLatin1.test_unicode_to_argv_py3
     116allmydata.test.test_encodingutil.UbuntuKarmicLatin1.test_unicode_to_output
     117allmydata.test.test_encodingutil.UbuntuKarmicLatin1.test_unicode_to_url
     118allmydata.test.test_encodingutil.UbuntuKarmicUTF8.test_argv_to_unicode
     119allmydata.test.test_encodingutil.UbuntuKarmicUTF8.test_listdir_unicode
     120allmydata.test.test_encodingutil.UbuntuKarmicUTF8.test_unicode_platform_py3
     121allmydata.test.test_encodingutil.UbuntuKarmicUTF8.test_unicode_to_argv_py3
     122allmydata.test.test_encodingutil.UbuntuKarmicUTF8.test_unicode_to_output
     123allmydata.test.test_encodingutil.UbuntuKarmicUTF8.test_unicode_to_url
     124allmydata.test.test_encodingutil.Windows.test_argv_to_unicode
     125allmydata.test.test_encodingutil.Windows.test_unicode_platform_py3
     126allmydata.test.test_encodingutil.Windows.test_unicode_to_argv_py3
     127allmydata.test.test_encodingutil.Windows.test_unicode_to_output
     128allmydata.test.test_encodingutil.Windows.test_unicode_to_url
     129allmydata.test.test_happiness.Happiness.test_100
     130allmydata.test.test_happiness.Happiness.test_calc_happy
     131allmydata.test.test_happiness.Happiness.test_everything_broken
     132allmydata.test.test_happiness.Happiness.test_hypothesis0
     133allmydata.test.test_happiness.Happiness.test_hypothesis_0
     134allmydata.test.test_happiness.Happiness.test_hypothesis_1
     135allmydata.test.test_happiness.Happiness.test_placement_1
     136allmydata.test.test_happiness.Happiness.test_placement_simple
     137allmydata.test.test_happiness.Happiness.test_redistribute
     138allmydata.test.test_happiness.Happiness.test_unhappy
     139allmydata.test.test_happiness.HappinessUtils.test_residual_0
     140allmydata.test.test_happiness.HappinessUtils.test_trivial_flow_graph
     141allmydata.test.test_happiness.HappinessUtils.test_trivial_maximum_graph
     142allmydata.test.test_happiness.PlacementTests.test_hypothesis_unhappy
     143allmydata.test.test_happiness.PlacementTests.test_more_hypothesis
    73144allmydata.test.test_hashtree.Complete.test_create
    74145allmydata.test.test_hashtree.Complete.test_dump
     
    144215allmydata.test.test_time_format.TimeFormat.test_parse_date
    145216allmydata.test.test_time_format.TimeFormat.test_parse_duration
     217allmydata.test.test_util.FileUtil.test_abspath_expanduser_unicode
     218allmydata.test.test_util.FileUtil.test_create_long_path
     219allmydata.test.test_util.FileUtil.test_disk_stats
     220allmydata.test.test_util.FileUtil.test_disk_stats_avail_nonnegative
     221allmydata.test.test_util.FileUtil.test_du
     222allmydata.test.test_util.FileUtil.test_encrypted_tempfile
     223allmydata.test.test_util.FileUtil.test_get_pathinfo
     224allmydata.test.test_util.FileUtil.test_get_pathinfo_symlink
     225allmydata.test.test_util.FileUtil.test_make_dirs_with_absolute_mode
     226allmydata.test.test_util.FileUtil.test_remove_if_possible
     227allmydata.test.test_util.FileUtil.test_rename
     228allmydata.test.test_util.FileUtil.test_rename_no_overwrite
     229allmydata.test.test_util.FileUtil.test_replace_file
     230allmydata.test.test_util.FileUtil.test_rm_dir
     231allmydata.test.test_util.FileUtil.test_windows_expanduser_win7
     232allmydata.test.test_util.FileUtil.test_windows_expanduser_xp
     233allmydata.test.test_util.FileUtil.test_write_atomically
     234allmydata.test.test_util.IDLib.test_nodeid_b2a
     235allmydata.test.test_util.Math.test_round_sigfigs
     236allmydata.test.test_util.PollMixinTests.test_PollMixin_False_then_True
     237allmydata.test.test_util.PollMixinTests.test_PollMixin_True
     238allmydata.test.test_util.PollMixinTests.test_timeout
     239allmydata.test.test_util.YAML.test_convert
    146240allmydata.test.test_version.CheckRequirement.test_cross_check
    147241allmydata.test.test_version.CheckRequirement.test_cross_check_unparseable_versions
  • TabularUnified misc/python3/ratchet.sh

    r1037854 r6e24def  
    1010cd "../.."
    1111
    12 # Since both of the next calls are expected to exit non-0, relax our guard.
    13 set +e
    14 SUBUNITREPORTER_OUTPUT_PATH="$base/results.subunit2" trial --reporter subunitv2-file allmydata
    15 subunit2junitxml < "$base/results.subunit2" > "$base/results.xml"
    16 set -e
     12export SUBUNITREPORTER_OUTPUT_PATH="$base/results.subunit2"
     13# Since the next two calls are expected to exit non-0, relax our guard.
     14trial --reporter=subunitv2-file allmydata || true
     15subunit2junitxml < "${SUBUNITREPORTER_OUTPUT_PATH}" > "$base/results.xml" || true
    1716
    1817# Okay, now we're clear.
     
    3332  export TERM=ansi
    3433fi
    35 git diff "$tracking_filename"
    3634
    37 exit $code
     35echo "The ${tracking_filename} diff is:"
     36echo "================================="
     37# "git diff" gets pretty confused in this execution context when trying to
     38# write to stdout.  Somehow it fails with SIGTTOU.
     39git diff -- "${tracking_filename}" > tracking.diff
     40cat tracking.diff
     41echo "================================="
     42
     43echo "Exiting with code ${code} from ratchet.py."
     44exit ${code}
  • TabularUnified src/allmydata/client.py

    r1037854 r6e24def  
    742742        private_key, public_key = ed25519.signing_keypair_from_string(private_key_str)
    743743        public_key_str = ed25519.string_from_verifying_key(public_key)
    744         self.config.write_config_file("node.pubkey", public_key_str + "\n")
     744        self.config.write_config_file("node.pubkey", public_key_str + "\n", "w")
    745745        self._node_private_key = private_key
    746746        self._node_public_key = public_key
  • TabularUnified src/allmydata/dirnode.py

    r1037854 r6e24def  
    11"""Directory Node implementation."""
    2 import time, unicodedata
     2import time
    33
    44from zope.interface import implementer
     
    1919from allmydata.monitor import Monitor
    2020from allmydata.util import hashutil, base32, log
    21 from allmydata.util.encodingutil import quote_output
     21from allmydata.util.encodingutil import quote_output, normalize
    2222from allmydata.util.assertutil import precondition
    2323from allmydata.util.netstring import netstring, split_netstring
     
    101101    return metadata
    102102
    103 
    104 # 'x' at the end of a variable name indicates that it holds a Unicode string that may not
    105 # be NFC-normalized.
    106 
    107 def normalize(namex):
    108     return unicodedata.normalize('NFC', namex)
    109103
    110104# TODO: {Deleter,MetadataSetter,Adder}.modify all start by unpacking the
  • TabularUnified src/allmydata/immutable/happiness_upload.py

    r1037854 r6e24def  
    1 
    2 from Queue import PriorityQueue
     1"""
     2Algorithms for figuring out happiness, the number of unique nodes the data is
     3on.
     4
     5Ported to Python 3.
     6"""
     7from __future__ import absolute_import
     8from __future__ import division
     9from __future__ import print_function
     10from __future__ import unicode_literals
     11
     12from future.utils import PY2
     13if PY2:
     14    # We omit dict, just in case newdict breaks things for external Python 2 code.
     15    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
     16
     17from queue import PriorityQueue
    318
    419
     
    3651    # BLACK vertices are those we have seen and explored
    3752    BLACK = 2
    38     color        = [WHITE for i in xrange(len(graph))]
    39     predecessor  = [None for i in xrange(len(graph))]
    40     distance     = [-1 for i in xrange(len(graph))]
     53    color        = [WHITE for i in range(len(graph))]
     54    predecessor  = [None for i in range(len(graph))]
     55    distance     = [-1 for i in range(len(graph))]
    4156    queue = [s] # vertices that we haven't explored yet.
    4257    color[s] = GRAY
     
    5974    flow network in adjacency-list form, and f is a flow in graph.
    6075    """
    61     new_graph = [[] for i in xrange(len(graph))]
    62     cf = [[0 for s in xrange(len(graph))] for sh in xrange(len(graph))]
    63     for i in xrange(len(graph)):
     76    new_graph = [[] for i in range(len(graph))]
     77    cf = [[0 for s in range(len(graph))] for sh in range(len(graph))]
     78    for i in range(len(graph)):
    6479        for v in graph[i]:
    6580            if f[i][v] == 1:
     
    136151
    137152    dim = len(graph)
    138     flow_function = [[0 for sh in xrange(dim)] for s in xrange(dim)]
     153    flow_function = [[0 for sh in range(dim)] for s in range(dim)]
    139154    residual_graph, residual_function = residual_network(graph, flow_function)
    140155
     
    261276    #print "servermap %s" % servermap
    262277    for peer in peers:
    263         if servermap.has_key(peer):
     278        if peer in servermap:
    264279            for s in servermap[peer]:
    265                 if share_to_index.has_key(s):
     280                if s in share_to_index:
    266281                    indexedShares.append(share_to_index[s])
    267282        graph.insert(peer_to_index[peer], indexedShares)
     
    374389    #print "new_peers %s" % new_peers
    375390    #print "new_mappings %s" % new_mappings
    376     mappings = dict(readonly_mappings.items() + existing_mappings.items() + new_mappings.items())
     391    mappings = dict(list(readonly_mappings.items()) + list(existing_mappings.items()) + list(new_mappings.items()))
    377392    homeless_shares = set()
    378393    for share in mappings:
     
    385400            {
    386401                k: v
    387                 for k, v in peers_to_shares.items()
     402                for k, v in list(peers_to_shares.items())
    388403                if k not in readonly_peers
    389404            }
     
    402417    return {
    403418        k: v.pop() if v else next(peer_iter)
    404         for k, v in mappings.items()
     419        for k, v in list(mappings.items())
    405420    }
  • TabularUnified src/allmydata/test/common_py3.py

    r1037854 r6e24def  
    1414    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
    1515
     16from past.builtins import unicode
     17
    1618import os
    1719import time
     
    1921
    2022from twisted.internet import reactor
     23from twisted.trial import unittest
     24
     25from ..util.assertutil import precondition
     26from ..util.encodingutil import unicode_platform, get_filesystem_encoding
    2127
    2228
     
    6672            signal.signal(signal.SIGCHLD, self.sigchldHandler)
    6773        return super(SignalMixin, self).tearDown()
     74
     75
     76class ReallyEqualMixin(object):
     77    def failUnlessReallyEqual(self, a, b, msg=None):
     78        self.assertEqual(a, b, msg)
     79        self.assertEqual(type(a), type(b), "a :: %r, b :: %r, %r" % (a, b, msg))
     80
     81
     82def skip_if_cannot_represent_filename(u):
     83    precondition(isinstance(u, unicode))
     84
     85    enc = get_filesystem_encoding()
     86    if not unicode_platform():
     87        try:
     88            u.encode(enc)
     89        except UnicodeEncodeError:
     90            raise unittest.SkipTest("A non-ASCII filename could not be encoded on this platform.")
  • TabularUnified src/allmydata/test/common_util.py

    r1037854 r6e24def  
    1010
    1111from ..util.assertutil import precondition
    12 from allmydata.util.encodingutil import (unicode_platform, get_filesystem_encoding,
    13                                          get_io_encoding)
    14 from ..scripts import runner
    15 from .common_py3 import SignalMixin
     12from allmydata.util.encodingutil import get_io_encoding
     13from future.utils import PY2
     14if PY2: # XXX this is a hack that makes some tests pass on Python3, remove
     15        # in the future
     16    from ..scripts import runner
     17# Imported for backwards compatibility:
     18from .common_py3 import (
     19    SignalMixin, skip_if_cannot_represent_filename, ReallyEqualMixin,
     20)
    1621
    17 
    18 def skip_if_cannot_represent_filename(u):
    19     precondition(isinstance(u, unicode))
    20 
    21     enc = get_filesystem_encoding()
    22     if not unicode_platform():
    23         try:
    24             u.encode(enc)
    25         except UnicodeEncodeError:
    26             raise unittest.SkipTest("A non-ASCII filename could not be encoded on this platform.")
    2722
    2823def skip_if_cannot_represent_argv(u):
     
    8378    assert result != s, "Internal error -- flip_one_bit() produced the same string as its input: %s == %s" % (result, s)
    8479    return result
    85 
    86 
    87 class ReallyEqualMixin(object):
    88     def failUnlessReallyEqual(self, a, b, msg=None):
    89         self.assertEqual(a, b, msg)
    90         self.assertEqual(type(a), type(b), "a :: %r, b :: %r, %r" % (a, b, msg))
    9180
    9281
     
    184173    make_readonly = _make_readonly
    185174    make_accessible = _make_accessible
     175
     176
     177__all__ = [
     178    "make_readonly", "make_accessible", "TestMixin", "ShouldFailMixin",
     179    "StallMixin", "skip_if_cannot_represent_argv", "run_cli", "parse_cli",
     180    "DevNullDictionary", "insecurerandstr", "flip_bit", "flip_one_bit",
     181    "SignalMixin", "skip_if_cannot_represent_filename", "ReallyEqualMixin"
     182]
  • TabularUnified src/allmydata/test/test_encodingutil.py

    r1037854 r6e24def  
    11from __future__ import print_function
     2from __future__ import absolute_import
     3from __future__ import division
     4from __future__ import unicode_literals
     5
     6from future.utils import PY2, PY3
     7if PY2:
     8    # We don't import str because omg way too ambiguous in this context.
     9    from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, max, min  # noqa: F401
     10
     11from past.builtins import unicode
    212
    313lumiere_nfc = u"lumi\u00E8re"
     
    4454            open(os.path.join(tmpdir, fname), 'w').close()
    4555
    46         # Use Unicode API under Windows or MacOS X
    47         if sys.platform in ('win32', 'darwin'):
     56        # On Python 2, listing directories returns unicode under Windows or
     57        # MacOS X if the input is unicode. On Python 3, it always returns
     58        # Unicode.
     59        if PY2 and sys.platform in ('win32', 'darwin'):
    4860            dirlist = os.listdir(unicode(tmpdir))
    4961        else:
     
    6072
    6173import os, sys, locale
     74from unittest import skipIf
    6275
    6376from twisted.trial import unittest
     
    6578from twisted.python.filepath import FilePath
    6679
    67 from allmydata.test.common_util import ReallyEqualMixin
     80from allmydata.test.common_py3 import (
     81    ReallyEqualMixin, skip_if_cannot_represent_filename,
     82)
    6883from allmydata.util import encodingutil, fileutil
    6984from allmydata.util.encodingutil import argv_to_unicode, unicode_to_url, \
     
    7186    quote_filepath, unicode_platform, listdir_unicode, FilenameEncodingError, \
    7287    get_io_encoding, get_filesystem_encoding, to_str, from_utf8_or_none, _reload, \
    73     to_filepath, extend_filepath, unicode_from_filepath, unicode_segments_from
    74 from allmydata.dirnode import normalize
    75 from .common_util import skip_if_cannot_represent_filename
     88    to_filepath, extend_filepath, unicode_from_filepath, unicode_segments_from, \
     89    unicode_to_argv
    7690from twisted.python import usage
    7791
     
    91105        mock_stdout.encoding = 'cp65001'
    92106        _reload()
    93         self.failUnlessReallyEqual(get_io_encoding(), 'utf-8')
     107        self.assertEqual(get_io_encoding(), 'utf-8')
    94108
    95109        mock_stdout.encoding = 'koi8-r'
     
    123137        preferredencoding = None
    124138        _reload()
    125         self.failUnlessReallyEqual(get_io_encoding(), 'utf-8')
     139        self.assertEqual(get_io_encoding(), 'utf-8')
    126140
    127141    def test_argv_to_unicode(self):
     
    151165# Unicode entities on the filesystem.
    152166class EncodingUtilNonUnicodePlatform(unittest.TestCase):
     167    @skipIf(PY3, "Python 3 is always Unicode, regardless of OS.")
    153168    def setUp(self):
    154169        # Mock sys.platform because unicode_platform() uses it
     
    212227
    213228    def test_unicode_to_url(self):
    214         self.failUnless(unicode_to_url(lumiere_nfc), "lumi\xc3\xa8re")
     229        self.failUnless(unicode_to_url(lumiere_nfc), b"lumi\xc3\xa8re")
    215230
    216231    def test_unicode_to_output(self):
     
    225240        self.failUnlessReallyEqual(unicode_to_output(lumiere_nfc), self.argv)
    226241
    227     def test_unicode_platform(self):
     242    @skipIf(PY3, "Python 2 only.")
     243    def test_unicode_to_argv_py2(self):
     244        """unicode_to_argv() converts to bytes on Python 2."""
     245        self.assertEqual(unicode_to_argv("abc"), u"abc".encode(self.io_encoding))
     246
     247    @skipIf(PY2, "Python 3 only.")
     248    def test_unicode_to_argv_py3(self):
     249        """unicode_to_argv() is noop on Python 3."""
     250        self.assertEqual(unicode_to_argv("abc"), "abc")
     251
     252    @skipIf(PY3, "Python 3 only.")
     253    def test_unicode_platform_py2(self):
    228254        matrix = {
    229255          'linux2': False,
     
    237263        self.failUnlessReallyEqual(unicode_platform(), matrix[self.platform])
    238264
     265    @skipIf(PY2, "Python 3 isn't Python 2.")
     266    def test_unicode_platform_py3(self):
     267        _reload()
     268        self.failUnlessReallyEqual(unicode_platform(), True)
     269
    239270    def test_listdir_unicode(self):
    240271        if 'dirlist' not in dir(self):
     
    249280
    250281        def call_os_listdir(path):
    251             return self.dirlist
     282            if PY2:
     283                return self.dirlist
     284            else:
     285                # Python 3 always lists unicode filenames:
     286                return [d.decode(self.filesystem_encoding) if isinstance(d, bytes)
     287                        else d
     288                        for d in self.dirlist]
     289   
    252290        self.patch(os, 'listdir', call_os_listdir)
    253291
     
    259297        filenames = listdir_unicode(u'/dummy')
    260298
    261         self.failUnlessEqual(set([normalize(fname) for fname in filenames]),
     299        self.failUnlessEqual(set([encodingutil.normalize(fname) for fname in filenames]),
    262300                             set(TEST_FILENAMES))
    263301
     
    279317        open(fn, 'wb').close()
    280318        self.failUnless(os.path.exists(fn))
    281         self.failUnless(os.path.exists(os.path.join(os.getcwdu(), fn)))
     319        if PY2:
     320            getcwdu = os.getcwdu
     321        else:
     322            getcwdu = os.getcwd
     323        self.failUnless(os.path.exists(os.path.join(getcwdu(), fn)))
    282324        filenames = listdir_unicode(lumiere_nfc)
    283325
    284326        # We only require that the listing includes a filename that is canonically equivalent
    285327        # to lumiere_nfc (on Mac OS X, it will be the NFD equivalent).
    286         self.failUnlessIn(lumiere_nfc + ".txt", set([normalize(fname) for fname in filenames]))
     328        self.failUnlessIn(lumiere_nfc + u".txt", set([encodingutil.normalize(fname) for fname in filenames]))
    287329
    288330        expanded = fileutil.expanduser(u"~/" + lumiere_nfc)
     
    315357        if out[0:2] == 'b"':
    316358            pass
    317         elif isinstance(inp, str):
    318             self.failUnlessReallyEqual(quote_output(unicode(inp), encoding=enc, quote_newlines=quote_newlines), out)
    319             self.failUnlessReallyEqual(quote_output(unicode(inp), encoding=enc, quotemarks=False, quote_newlines=quote_newlines), out2)
     359        elif isinstance(inp, bytes):
     360            try:
     361                unicode_inp = inp.decode("utf-8")
     362            except UnicodeDecodeError:
     363                # Some things decode on Python 2, but not Python 3...
     364                return
     365            self.failUnlessReallyEqual(quote_output(unicode_inp, encoding=enc, quote_newlines=quote_newlines), out)
     366            self.failUnlessReallyEqual(quote_output(unicode_inp, encoding=enc, quotemarks=False, quote_newlines=quote_newlines), out2)
    320367        else:
    321             self.failUnlessReallyEqual(quote_output(inp.encode('utf-8'), encoding=enc, quote_newlines=quote_newlines), out)
    322             self.failUnlessReallyEqual(quote_output(inp.encode('utf-8'), encoding=enc, quotemarks=False, quote_newlines=quote_newlines), out2)
     368            try:
     369                bytes_inp = inp.encode('utf-8')
     370            except UnicodeEncodeError:
     371                # Some things encode on Python 2, but not Python 3, e.g.
     372                # surrogates like u"\uDC00\uD800"...
     373                return
     374            self.failUnlessReallyEqual(quote_output(bytes_inp, encoding=enc, quote_newlines=quote_newlines), out)
     375            self.failUnlessReallyEqual(quote_output(bytes_inp, encoding=enc, quotemarks=False, quote_newlines=quote_newlines), out2)
    323376
    324377    def _test_quote_output_all(self, enc):
     
    327380
    328381        # optional single quotes
    329         check("foo",  "'foo'",  True)
    330         check("\\",   "'\\'",   True)
    331         check("$\"`", "'$\"`'", True)
    332         check("\n",   "'\n'",   True, quote_newlines=False)
     382        check(b"foo",  b"'foo'",  True)
     383        check(b"\\",   b"'\\'",   True)
     384        check(b"$\"`", b"'$\"`'", True)
     385        check(b"\n",   b"'\n'",   True, quote_newlines=False)
    333386
    334387        # mandatory single quotes
    335         check("\"",   "'\"'")
     388        check(b"\"",   b"'\"'")
    336389
    337390        # double quotes
    338         check("'",    "\"'\"")
    339         check("\n",   "\"\\x0a\"", quote_newlines=True)
    340         check("\x00", "\"\\x00\"")
     391        check(b"'",    b"\"'\"")
     392        check(b"\n",   b"\"\\x0a\"", quote_newlines=True)
     393        check(b"\x00", b"\"\\x00\"")
    341394
    342395        # invalid Unicode and astral planes
    343         check(u"\uFDD0\uFDEF",       "\"\\ufdd0\\ufdef\"")
    344         check(u"\uDC00\uD800",       "\"\\udc00\\ud800\"")
    345         check(u"\uDC00\uD800\uDC00", "\"\\udc00\\U00010000\"")
    346         check(u"\uD800\uDC00",       "\"\\U00010000\"")
    347         check(u"\uD800\uDC01",       "\"\\U00010001\"")
    348         check(u"\uD801\uDC00",       "\"\\U00010400\"")
    349         check(u"\uDBFF\uDFFF",       "\"\\U0010ffff\"")
    350         check(u"'\uDBFF\uDFFF",      "\"'\\U0010ffff\"")
    351         check(u"\"\uDBFF\uDFFF",     "\"\\\"\\U0010ffff\"")
     396        check(u"\uFDD0\uFDEF",       b"\"\\ufdd0\\ufdef\"")
     397        check(u"\uDC00\uD800",       b"\"\\udc00\\ud800\"")
     398        check(u"\uDC00\uD800\uDC00", b"\"\\udc00\\U00010000\"")
     399        check(u"\uD800\uDC00",       b"\"\\U00010000\"")
     400        check(u"\uD800\uDC01",       b"\"\\U00010001\"")
     401        check(u"\uD801\uDC00",       b"\"\\U00010400\"")
     402        check(u"\uDBFF\uDFFF",       b"\"\\U0010ffff\"")
     403        check(u"'\uDBFF\uDFFF",      b"\"'\\U0010ffff\"")
     404        check(u"\"\uDBFF\uDFFF",     b"\"\\\"\\U0010ffff\"")
    352405
    353406        # invalid UTF-8
    354         check("\xFF",                "b\"\\xff\"")
    355         check("\x00\"$\\`\x80\xFF",  "b\"\\x00\\\"\\$\\\\\\`\\x80\\xff\"")
     407        check(b"\xFF",                b"b\"\\xff\"")
     408        check(b"\x00\"$\\`\x80\xFF",  b"b\"\\x00\\\"\\$\\\\\\`\\x80\\xff\"")
    356409
    357410    def test_quote_output_ascii(self, enc='ascii'):
     
    360413
    361414        self._test_quote_output_all(enc)
    362         check(u"\u00D7",   "\"\\xd7\"")
    363         check(u"'\u00D7",  "\"'\\xd7\"")
    364         check(u"\"\u00D7", "\"\\\"\\xd7\"")
    365         check(u"\u2621",   "\"\\u2621\"")
    366         check(u"'\u2621",  "\"'\\u2621\"")
    367         check(u"\"\u2621", "\"\\\"\\u2621\"")
    368         check(u"\n",       "'\n'",      True, quote_newlines=False)
    369         check(u"\n",       "\"\\x0a\"", quote_newlines=True)
     415        check(u"\u00D7",   b"\"\\xd7\"")
     416        check(u"'\u00D7",  b"\"'\\xd7\"")
     417        check(u"\"\u00D7", b"\"\\\"\\xd7\"")
     418        check(u"\u2621",   b"\"\\u2621\"")
     419        check(u"'\u2621",  b"\"'\\u2621\"")
     420        check(u"\"\u2621", b"\"\\\"\\u2621\"")
     421        check(u"\n",       b"'\n'",      True, quote_newlines=False)
     422        check(u"\n",       b"\"\\x0a\"", quote_newlines=True)
    370423
    371424    def test_quote_output_latin1(self, enc='latin1'):
     
    412465class QuotePaths(ReallyEqualMixin, unittest.TestCase):
    413466    def test_quote_path(self):
    414         self.failUnlessReallyEqual(quote_path([u'foo', u'bar']), "'foo/bar'")
    415         self.failUnlessReallyEqual(quote_path([u'foo', u'bar'], quotemarks=True), "'foo/bar'")
    416         self.failUnlessReallyEqual(quote_path([u'foo', u'bar'], quotemarks=False), "foo/bar")
    417         self.failUnlessReallyEqual(quote_path([u'foo', u'\nbar']), '"foo/\\x0abar"')
    418         self.failUnlessReallyEqual(quote_path([u'foo', u'\nbar'], quotemarks=True), '"foo/\\x0abar"')
    419         self.failUnlessReallyEqual(quote_path([u'foo', u'\nbar'], quotemarks=False), '"foo/\\x0abar"')
     467        self.failUnlessReallyEqual(quote_path([u'foo', u'bar']), b"'foo/bar'")
     468        self.failUnlessReallyEqual(quote_path([u'foo', u'bar'], quotemarks=True), b"'foo/bar'")
     469        self.failUnlessReallyEqual(quote_path([u'foo', u'bar'], quotemarks=False), b"foo/bar")
     470        self.failUnlessReallyEqual(quote_path([u'foo', u'\nbar']), b'"foo/\\x0abar"')
     471        self.failUnlessReallyEqual(quote_path([u'foo', u'\nbar'], quotemarks=True), b'"foo/\\x0abar"')
     472        self.failUnlessReallyEqual(quote_path([u'foo', u'\nbar'], quotemarks=False), b'"foo/\\x0abar"')
    420473
    421474        self.failUnlessReallyEqual(quote_local_unicode_path(u"\\\\?\\C:\\foo"),
    422                                    win32_other("'C:\\foo'", "'\\\\?\\C:\\foo'"))
     475                                   win32_other(b"'C:\\foo'", b"'\\\\?\\C:\\foo'"))
    423476        self.failUnlessReallyEqual(quote_local_unicode_path(u"\\\\?\\C:\\foo", quotemarks=True),
    424                                    win32_other("'C:\\foo'", "'\\\\?\\C:\\foo'"))
     477                                   win32_other(b"'C:\\foo'", b"'\\\\?\\C:\\foo'"))
    425478        self.failUnlessReallyEqual(quote_local_unicode_path(u"\\\\?\\C:\\foo", quotemarks=False),
    426                                    win32_other("C:\\foo", "\\\\?\\C:\\foo"))
     479                                   win32_other(b"C:\\foo", b"\\\\?\\C:\\foo"))
    427480        self.failUnlessReallyEqual(quote_local_unicode_path(u"\\\\?\\UNC\\foo\\bar"),
    428                                    win32_other("'\\\\foo\\bar'", "'\\\\?\\UNC\\foo\\bar'"))
     481                                   win32_other(b"'\\\\foo\\bar'", b"'\\\\?\\UNC\\foo\\bar'"))
    429482        self.failUnlessReallyEqual(quote_local_unicode_path(u"\\\\?\\UNC\\foo\\bar", quotemarks=True),
    430                                    win32_other("'\\\\foo\\bar'", "'\\\\?\\UNC\\foo\\bar'"))
     483                                   win32_other(b"'\\\\foo\\bar'", b"'\\\\?\\UNC\\foo\\bar'"))
    431484        self.failUnlessReallyEqual(quote_local_unicode_path(u"\\\\?\\UNC\\foo\\bar", quotemarks=False),
    432                                    win32_other("\\\\foo\\bar", "\\\\?\\UNC\\foo\\bar"))
     485                                   win32_other(b"\\\\foo\\bar", b"\\\\?\\UNC\\foo\\bar"))
    433486
    434487    def test_quote_filepath(self):
    435488        foo_bar_fp = FilePath(win32_other(u'C:\\foo\\bar', u'/foo/bar'))
    436489        self.failUnlessReallyEqual(quote_filepath(foo_bar_fp),
    437                                    win32_other("'C:\\foo\\bar'", "'/foo/bar'"))
     490                                   win32_other(b"'C:\\foo\\bar'", b"'/foo/bar'"))
    438491        self.failUnlessReallyEqual(quote_filepath(foo_bar_fp, quotemarks=True),
    439                                    win32_other("'C:\\foo\\bar'", "'/foo/bar'"))
     492                                   win32_other(b"'C:\\foo\\bar'", b"'/foo/bar'"))
    440493        self.failUnlessReallyEqual(quote_filepath(foo_bar_fp, quotemarks=False),
    441                                    win32_other("C:\\foo\\bar", "/foo/bar"))
     494                                   win32_other(b"C:\\foo\\bar", b"/foo/bar"))
    442495
    443496        if sys.platform == "win32":
    444497            foo_longfp = FilePath(u'\\\\?\\C:\\foo')
    445498            self.failUnlessReallyEqual(quote_filepath(foo_longfp),
    446                                        "'C:\\foo'")
     499                                       b"'C:\\foo'")
    447500            self.failUnlessReallyEqual(quote_filepath(foo_longfp, quotemarks=True),
    448                                        "'C:\\foo'")
     501                                       b"'C:\\foo'")
    449502            self.failUnlessReallyEqual(quote_filepath(foo_longfp, quotemarks=False),
    450                                        "C:\\foo")
     503                                       b"C:\\foo")
    451504
    452505
     
    502555class UbuntuKarmicUTF8(EncodingUtil, unittest.TestCase):
    503556    uname = 'Linux korn 2.6.31-14-generic #48-Ubuntu SMP Fri Oct 16 14:05:01 UTC 2009 x86_64'
    504     argv = 'lumi\xc3\xa8re'
     557    argv = b'lumi\xc3\xa8re'
    505558    platform = 'linux2'
    506559    filesystem_encoding = 'UTF-8'
    507560    io_encoding = 'UTF-8'
    508     dirlist = ['test_file', '\xc3\x84rtonwall.mp3', 'Blah blah.txt']
     561    dirlist = [b'test_file', b'\xc3\x84rtonwall.mp3', b'Blah blah.txt']
    509562
    510563class UbuntuKarmicLatin1(EncodingUtil, unittest.TestCase):
    511564    uname = 'Linux korn 2.6.31-14-generic #48-Ubuntu SMP Fri Oct 16 14:05:01 UTC 2009 x86_64'
    512     argv = 'lumi\xe8re'
     565    argv = b'lumi\xe8re'
    513566    platform = 'linux2'
    514567    filesystem_encoding = 'ISO-8859-1'
    515568    io_encoding = 'ISO-8859-1'
    516     dirlist = ['test_file', 'Blah blah.txt', '\xc4rtonwall.mp3']
     569    dirlist = [b'test_file', b'Blah blah.txt', b'\xc4rtonwall.mp3']
    517570
    518571class Windows(EncodingUtil, unittest.TestCase):
    519572    uname = 'Windows XP 5.1.2600 x86 x86 Family 15 Model 75 Step ping 2, AuthenticAMD'
    520     argv = 'lumi\xc3\xa8re'
     573    argv = b'lumi\xc3\xa8re'
    521574    platform = 'win32'
    522575    filesystem_encoding = 'mbcs'
     
    526579class MacOSXLeopard(EncodingUtil, unittest.TestCase):
    527580    uname = 'Darwin g5.local 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:57:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_PPC Power Macintosh powerpc'
    528     output = 'lumi\xc3\xa8re'
     581    output = b'lumi\xc3\xa8re'
    529582    platform = 'darwin'
    530583    filesystem_encoding = 'utf-8'
     
    549602class TestToFromStr(ReallyEqualMixin, unittest.TestCase):
    550603    def test_to_str(self):
    551         self.failUnlessReallyEqual(to_str("foo"), "foo")
    552         self.failUnlessReallyEqual(to_str("lumi\xc3\xa8re"), "lumi\xc3\xa8re")
    553         self.failUnlessReallyEqual(to_str("\xFF"), "\xFF")  # passes through invalid UTF-8 -- is this what we want?
    554         self.failUnlessReallyEqual(to_str(u"lumi\u00E8re"), "lumi\xc3\xa8re")
     604        self.failUnlessReallyEqual(to_str(b"foo"), b"foo")
     605        self.failUnlessReallyEqual(to_str(b"lumi\xc3\xa8re"), b"lumi\xc3\xa8re")
     606        self.failUnlessReallyEqual(to_str(b"\xFF"), b"\xFF")  # passes through invalid UTF-8 -- is this what we want?
     607        self.failUnlessReallyEqual(to_str(u"lumi\u00E8re"), b"lumi\xc3\xa8re")
    555608        self.failUnlessReallyEqual(to_str(None), None)
    556609
    557610    def test_from_utf8_or_none(self):
    558611        self.failUnlessRaises(AssertionError, from_utf8_or_none, u"foo")
    559         self.failUnlessReallyEqual(from_utf8_or_none("lumi\xc3\xa8re"), u"lumi\u00E8re")
     612        self.failUnlessReallyEqual(from_utf8_or_none(b"lumi\xc3\xa8re"), u"lumi\u00E8re")
    560613        self.failUnlessReallyEqual(from_utf8_or_none(None), None)
    561         self.failUnlessRaises(UnicodeDecodeError, from_utf8_or_none, "\xFF")
     614        self.failUnlessRaises(UnicodeDecodeError, from_utf8_or_none, b"\xFF")
  • TabularUnified src/allmydata/test/test_happiness.py

    r1037854 r6e24def  
    11# -*- coding: utf-8 -*-
     2
     3from __future__ import absolute_import
     4from __future__ import division
     5from __future__ import print_function
     6from __future__ import unicode_literals
     7
     8from future.utils import PY2
     9if PY2:
     10    # We omit dict, just in case newdict breaks things.
     11    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
    212
    313from twisted.trial import unittest
  • TabularUnified src/allmydata/test/test_util.py

    r1037854 r6e24def  
     1"""
     2Ported to Python3.
     3"""
     4
    15from __future__ import print_function
    2 
     6from __future__ import absolute_import
     7from __future__ import division
     8from __future__ import unicode_literals
     9
     10from future.utils import PY2
     11if PY2:
     12    from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, pow, round, super, bytes, dict, list, object, range, str, max, min  # noqa: F401
    313import six
    414import os, time, sys
     
    2030class IDLib(unittest.TestCase):
    2131    def test_nodeid_b2a(self):
    22         self.failUnlessEqual(idlib.nodeid_b2a("\x00"*20), "a"*32)
     32        self.failUnlessEqual(idlib.nodeid_b2a(b"\x00"*20), "a"*32)
    2333
    2434
     
    8696        fileutil.make_dirs(basedir)
    8797        fn = os.path.join(basedir, "here")
    88         fileutil.write_atomically(fn, "one")
    89         self.failUnlessEqual(fileutil.read(fn), "one")
    90         fileutil.write_atomically(fn, "two", mode="") # non-binary
    91         self.failUnlessEqual(fileutil.read(fn), "two")
     98        fileutil.write_atomically(fn, b"one", "b")
     99        self.failUnlessEqual(fileutil.read(fn), b"one")
     100        fileutil.write_atomically(fn, u"two", mode="") # non-binary
     101        self.failUnlessEqual(fileutil.read(fn), b"two")
    92102
    93103    def test_rename(self):
     
    112122
    113123        # when only dest exists
    114         fileutil.write(dest_path,   "dest")
     124        fileutil.write(dest_path,   b"dest")
    115125        self.failUnlessRaises(OSError, fileutil.rename_no_overwrite, source_path, dest_path)
    116         self.failUnlessEqual(fileutil.read(dest_path),   "dest")
     126        self.failUnlessEqual(fileutil.read(dest_path),   b"dest")
    117127
    118128        # when both exist
    119         fileutil.write(source_path, "source")
     129        fileutil.write(source_path, b"source")
    120130        self.failUnlessRaises(OSError, fileutil.rename_no_overwrite, source_path, dest_path)
    121         self.failUnlessEqual(fileutil.read(source_path), "source")
    122         self.failUnlessEqual(fileutil.read(dest_path),   "dest")
     131        self.failUnlessEqual(fileutil.read(source_path), b"source")
     132        self.failUnlessEqual(fileutil.read(dest_path),   b"dest")
    123133
    124134        # when only source exists
    125135        os.remove(dest_path)
    126136        fileutil.rename_no_overwrite(source_path, dest_path)
    127         self.failUnlessEqual(fileutil.read(dest_path), "source")
     137        self.failUnlessEqual(fileutil.read(dest_path), b"source")
    128138        self.failIf(os.path.exists(source_path))
    129139
     
    139149
    140150        # when only replaced exists
    141         fileutil.write(replaced_path,    "foo")
     151        fileutil.write(replaced_path,   b"foo")
    142152        self.failUnlessRaises(fileutil.ConflictError, fileutil.replace_file, replaced_path, replacement_path)
    143         self.failUnlessEqual(fileutil.read(replaced_path), "foo")
     153        self.failUnlessEqual(fileutil.read(replaced_path), b"foo")
    144154
    145155        # when both replaced and replacement exist
    146         fileutil.write(replacement_path, "bar")
     156        fileutil.write(replacement_path, b"bar")
    147157        fileutil.replace_file(replaced_path, replacement_path)
    148         self.failUnlessEqual(fileutil.read(replaced_path), "bar")
     158        self.failUnlessEqual(fileutil.read(replaced_path), b"bar")
    149159        self.failIf(os.path.exists(replacement_path))
    150160
    151161        # when only replacement exists
    152162        os.remove(replaced_path)
    153         fileutil.write(replacement_path, "bar")
     163        fileutil.write(replacement_path, b"bar")
    154164        fileutil.replace_file(replaced_path, replacement_path)
    155         self.failUnlessEqual(fileutil.read(replaced_path), "bar")
     165        self.failUnlessEqual(fileutil.read(replaced_path), b"bar")
    156166        self.failIf(os.path.exists(replacement_path))
    157167
     
    171181
    172182    def test_abspath_expanduser_unicode(self):
    173         self.failUnlessRaises(AssertionError, fileutil.abspath_expanduser_unicode, "bytestring")
    174 
    175         saved_cwd = os.path.normpath(os.getcwdu())
     183        self.failUnlessRaises(AssertionError, fileutil.abspath_expanduser_unicode, b"bytestring")
     184
     185        saved_cwd = os.path.normpath(os.getcwd())
     186        if PY2:
     187            saved_cwd = saved_cwd.decode("utf8")
    176188        abspath_cwd = fileutil.abspath_expanduser_unicode(u".")
    177189        abspath_cwd_notlong = fileutil.abspath_expanduser_unicode(u".", long_path=False)
    178         self.failUnless(isinstance(saved_cwd, unicode), saved_cwd)
    179         self.failUnless(isinstance(abspath_cwd, unicode), abspath_cwd)
     190        self.failUnless(isinstance(saved_cwd, str), saved_cwd)
     191        self.failUnless(isinstance(abspath_cwd, str), abspath_cwd)
    180192        if sys.platform == "win32":
    181193            self.failUnlessReallyEqual(abspath_cwd, fileutil.to_windows_long_path(saved_cwd))
     
    238250                for upath in (u'', u'fuu', u'f\xf9\xf9', u'/fuu', u'U:\\', u'~'):
    239251                    uabspath = fileutil.abspath_expanduser_unicode(upath)
    240                     self.failUnless(isinstance(uabspath, unicode), uabspath)
     252                    self.failUnless(isinstance(uabspath, str), uabspath)
    241253
    242254                    uabspath_notlong = fileutil.abspath_expanduser_unicode(upath, long_path=False)
    243                     self.failUnless(isinstance(uabspath_notlong, unicode), uabspath_notlong)
     255                    self.failUnless(isinstance(uabspath_notlong, str), uabspath_notlong)
    244256            finally:
    245257                os.chdir(saved_cwd)
     
    294306        self.addCleanup(_cleanup)
    295307
    296         fileutil.write(long_path, "test")
     308        fileutil.write(long_path, b"test")
    297309        self.failUnless(os.path.exists(long_path))
    298         self.failUnlessEqual(fileutil.read(long_path), "test")
     310        self.failUnlessEqual(fileutil.read(long_path), b"test")
    299311        _cleanup()
    300312        self.failIf(os.path.exists(long_path))
     
    354366        # create a file
    355367        f = os.path.join(basedir, "1.txt")
    356         fileutil.write(f, "a"*10)
     368        fileutil.write(f, b"a"*10)
    357369        fileinfo = fileutil.get_pathinfo(f)
    358370        self.failUnlessTrue(fileinfo.isfile)
     
    382394
    383395        f = os.path.join(basedir, "1.txt")
    384         fileutil.write(f, "a"*10)
     396        fileutil.write(f, b"a"*10)
    385397
    386398        # create a symlink pointing to 1.txt
     
    395407    def test_encrypted_tempfile(self):
    396408        f = EncryptedTemporaryFile()
    397         f.write("foobar")
     409        f.write(b"foobar")
    398410        f.close()
    399411
     
    410422    def test_PollMixin_False_then_True(self):
    411423        i = iter([False, True])
    412         d = self.pm.poll(check_f=i.next,
     424        d = self.pm.poll(check_f=lambda: next(i),
    413425                         pollinterval=0.1)
    414426        return d
     
    455467        data = yaml.safe_dump(["str", u"unicode", u"\u1234nicode"])
    456468        back = yamlutil.safe_load(data)
    457         self.failUnlessEqual(type(back[0]), unicode)
    458         self.failUnlessEqual(type(back[1]), unicode)
    459         self.failUnlessEqual(type(back[2]), unicode)
     469        self.assertIsInstance(back[0], str)
     470        self.assertIsInstance(back[1], str)
     471        self.assertIsInstance(back[2], str)
  • TabularUnified src/allmydata/util/_python3.py

    r1037854 r6e24def  
    2323    "allmydata.crypto.util",
    2424    "allmydata.hashtree",
     25    "allmydata.immutable.happiness_upload",
    2526    "allmydata.test.common_py3",
    2627    "allmydata.util._python3",
     
    3233    "allmydata.util.connection_status",
    3334    "allmydata.util.deferredutil",
     35    "allmydata.util.fileutil",
    3436    "allmydata.util.dictutil",
     37    "allmydata.util.encodingutil",
    3538    "allmydata.util.gcutil",
    3639    "allmydata.util.hashutil",
     
    5861    "allmydata.test.test_deferredutil",
    5962    "allmydata.test.test_dictutil",
     63    "allmydata.test.test_encodingutil",
     64    "allmydata.test.test_happiness",
    6065    "allmydata.test.test_hashtree",
    6166    "allmydata.test.test_hashutil",
     
    7075    "allmydata.test.test_statistics",
    7176    "allmydata.test.test_time_format",
     77    "allmydata.test.test_util",
    7278    "allmydata.test.test_version",
    7379]
    74 
    7580
    7681if __name__ == '__main__':
  • TabularUnified src/allmydata/util/encodingutil.py

    r1037854 r6e24def  
    22Functions used to convert inputs from whatever encoding used in the system to
    33unicode and back.
     4
     5Ported to Python 3.
     6
     7Once Python 2 support is dropped, most of this module will obsolete, since
     8Unicode is the default everywhere in Python 3.
    49"""
     10from __future__ import absolute_import
     11from __future__ import division
     12from __future__ import print_function
     13from __future__ import unicode_literals
     14
     15from future.utils import PY2, PY3, native_str
     16if PY2:
     17    # We omit str() because that seems too tricky to get right.
     18    from builtins import filter, map, zip, ascii, chr, hex, input, next, oct, open, pow, round, super, bytes, dict, list, object, range, max, min  # noqa: F401
     19
     20from past.builtins import unicode
    521
    622import sys, os, re, locale
     23import unicodedata
    724
    825from allmydata.util.assertutil import precondition, _assert
     
    6380    check_encoding(io_encoding)
    6481
    65     is_unicode_platform = sys.platform in ["win32", "darwin"]
     82    is_unicode_platform = PY3 or sys.platform in ["win32", "darwin"]
    6683
    6784    # Despite the Unicode-mode FilePath support added to Twisted in
    6885    # <https://twistedmatrix.com/trac/ticket/7805>, we can't yet use
    6986    # Unicode-mode FilePaths with INotify on non-Windows platforms
    70     # due to <https://twistedmatrix.com/trac/ticket/7928>.
    71     use_unicode_filepath = sys.platform == "win32"
     87    # due to <https://twistedmatrix.com/trac/ticket/7928>. Supposedly
     88    # 7928 is fixed, though...
     89    use_unicode_filepath = PY3 or sys.platform == "win32"
    7290
    7391_reload()
     
    90108    Decode given argv element to unicode. If this fails, raise a UsageError.
    91109    """
    92     precondition(isinstance(s, str), s)
     110    if isinstance(s, unicode):
     111        return s
     112
     113    precondition(isinstance(s, bytes), s)
    93114
    94115    try:
     
    115136    should be true; on Windows, this uses a mangled encoding that will be reversed by
    116137    code in runner.py.
     138
     139    On Python 3, just return the string unchanged, since argv is unicode.
    117140    """
    118141    precondition(isinstance(s, unicode), s)
     142    if PY3:
     143        return s
    119144
    120145    if mangle and sys.platform == "win32":
    121146        # This must be the same as 'mangle' in bin/tahoe-script.template.
    122         return str(re.sub(u'[^\\x20-\\x7F]', lambda m: u'\x7F%x;' % (ord(m.group(0)),), s))
     147        return bytes(re.sub(u'[^\\x20-\\x7F]', lambda m: u'\x7F%x;' % (ord(m.group(0)),), s), io_encoding)
    123148    else:
    124149        return s.encode(io_encoding)
     
    126151def unicode_to_url(s):
    127152    """
    128     Encode an unicode object used in an URL.
     153    Encode an unicode object used in an URL to bytes.
    129154    """
    130155    # According to RFC 2718, non-ascii characters in URLs must be UTF-8 encoded.
     
    135160    #return s.encode('utf-8')
    136161
    137 def to_str(s):
    138     if s is None or isinstance(s, str):
     162def to_str(s):  # TODO rename to to_bytes
     163    if s is None or isinstance(s, bytes):
    139164        return s
    140165    return s.encode('utf-8')
    141166
    142167def from_utf8_or_none(s):
    143     precondition(isinstance(s, (NoneType, str)), s)
     168    precondition(isinstance(s, bytes) or s is None, s)
    144169    if s is None:
    145170        return s
    146171    return s.decode('utf-8')
    147172
    148 PRINTABLE_ASCII = re.compile(r'^[\n\r\x20-\x7E]*$',          re.DOTALL)
    149 PRINTABLE_8BIT  = re.compile(r'^[\n\r\x20-\x7E\x80-\xFF]*$', re.DOTALL)
     173PRINTABLE_ASCII = re.compile(br'^[\n\r\x20-\x7E]*$',          re.DOTALL)
     174PRINTABLE_8BIT  = re.compile(br'^[\n\r\x20-\x7E\x80-\xFF]*$', re.DOTALL)
    150175
    151176def is_printable_ascii(s):
     
    161186        out = s.encode(io_encoding)
    162187    except (UnicodeEncodeError, UnicodeDecodeError):
    163         raise UnicodeEncodeError(io_encoding, s, 0, 0,
    164                                  "A string could not be encoded as %s for output to the terminal:\n%r" %
    165                                  (io_encoding, repr(s)))
     188        raise UnicodeEncodeError(native_str(io_encoding), s, 0, 0,
     189                                 native_str("A string could not be encoded as %s for output to the terminal:\n%r" %
     190                                 (io_encoding, repr(s))))
    166191
    167192    if PRINTABLE_8BIT.search(out) is None:
    168         raise UnicodeEncodeError(io_encoding, s, 0, 0,
    169                                  "A string encoded as %s for output to the terminal contained unsafe bytes:\n%r" %
    170                                  (io_encoding, repr(s)))
     193        raise UnicodeEncodeError(native_str(io_encoding), s, 0, 0,
     194                                 native_str("A string encoded as %s for output to the terminal contained unsafe bytes:\n%r" %
     195                                 (io_encoding, repr(s))))
    171196    return out
    172197
     
    189214        return u'\\x%02x' % (codepoint,)
    190215
    191 def _str_escape(m, quote_newlines):
     216def _str_escape(m, quote_newlines):  # TODO rename to _bytes_escape
     217    """
     218    Takes a re match on bytes, the result is escaped bytes of group(0).
     219    """
    192220    c = m.group(0)
    193     if c == '"' or c == '$' or c == '`' or c == '\\':
    194         return '\\' + c
    195     elif c == '\n' and not quote_newlines:
     221    if c == b'"' or c == b'$' or c == b'`' or c == b'\\':
     222        return b'\\' + c
     223    elif c == b'\n' and not quote_newlines:
    196224        return c
    197225    else:
    198         return '\\x%02x' % (ord(c),)
     226        return b'\\x%02x' % (ord(c),)
    199227
    200228MUST_DOUBLE_QUOTE_NL = re.compile(u'[^\\x20-\\x26\\x28-\\x7E\u00A0-\uD7FF\uE000-\uFDCF\uFDF0-\uFFFC]', re.DOTALL)
     
    206234                               re.DOTALL)
    207235
    208 ESCAPABLE_8BIT    = re.compile( r'[^ !#\x25-\x5B\x5D-\x5F\x61-\x7E]', re.DOTALL)
     236ESCAPABLE_8BIT    = re.compile( br'[^ !#\x25-\x5B\x5D-\x5F\x61-\x7E]', re.DOTALL)
    209237
    210238def quote_output(s, quotemarks=True, quote_newlines=None, encoding=None):
     
    222250    If not explicitly given, quote_newlines is True when quotemarks is True.
    223251    """
    224     precondition(isinstance(s, (str, unicode)), s)
     252    precondition(isinstance(s, (bytes, unicode)), s)
    225253    if quote_newlines is None:
    226254        quote_newlines = quotemarks
    227255
    228     if isinstance(s, str):
     256    if isinstance(s, bytes):
    229257        try:
    230258            s = s.decode('utf-8')
    231259        except UnicodeDecodeError:
    232             return 'b"%s"' % (ESCAPABLE_8BIT.sub(lambda m: _str_escape(m, quote_newlines), s),)
     260            return b'b"%s"' % (ESCAPABLE_8BIT.sub(lambda m: _str_escape(m, quote_newlines), s),)
    233261
    234262    must_double_quote = quote_newlines and MUST_DOUBLE_QUOTE_NL or MUST_DOUBLE_QUOTE
     
    236264        try:
    237265            out = s.encode(encoding or io_encoding)
    238             if quotemarks or out.startswith('"'):
    239                 return "'%s'" % (out,)
     266            if quotemarks or out.startswith(b'"'):
     267                return b"'%s'" % (out,)
    240268            else:
    241269                return out
     
    244272
    245273    escaped = ESCAPABLE_UNICODE.sub(lambda m: _unicode_escape(m, quote_newlines), s)
    246     return '"%s"' % (escaped.encode(encoding or io_encoding, 'backslashreplace'),)
     274    return b'"%s"' % (escaped.encode(encoding or io_encoding, 'backslashreplace'),)
    247275
    248276def quote_path(path, quotemarks=True):
    249     return quote_output("/".join(map(to_str, path)), quotemarks=quotemarks, quote_newlines=True)
     277    return quote_output(b"/".join(map(to_str, path)), quotemarks=quotemarks, quote_newlines=True)
    250278
    251279def quote_local_unicode_path(path, quotemarks=True):
     
    276304
    277305def to_filepath(path):
    278     precondition(isinstance(path, unicode if use_unicode_filepath else basestring),
     306    precondition(isinstance(path, unicode if use_unicode_filepath else (bytes, unicode)),
    279307                 path=path)
    280308
     
    291319
    292320def _decode(s):
    293     precondition(isinstance(s, basestring), s=s)
     321    precondition(isinstance(s, (bytes, unicode)), s=s)
    294322
    295323    if isinstance(s, bytes):
     
    357385def listdir_filepath(fp):
    358386    return listdir_unicode(unicode_from_filepath(fp))
     387
     388
     389# 'x' at the end of a variable name indicates that it holds a Unicode string that may not
     390# be NFC-normalized.
     391def normalize(namex):
     392    return unicodedata.normalize('NFC', namex)
  • TabularUnified src/allmydata/util/fileutil.py

    r1037854 r6e24def  
    1 from __future__ import print_function
    2 
    31"""
     2Ported to Python3.
     3
    44Futz with files like a pro.
    55"""
     6
     7from __future__ import print_function
     8from __future__ import absolute_import
     9from __future__ import division
     10from __future__ import unicode_literals
     11
     12from future.utils import PY2
     13if PY2:
     14    # open is not here because we want to use native strings on Py2
     15    from future.builtins import filter, map, zip, ascii, chr, hex, input, next, oct, pow, round, super, bytes, dict, list, object, range, str, max, min  # noqa: F401
    616
    717import sys, os, stat, tempfile, time, binascii
     
    254264
    255265def write_atomically(target, contents, mode="b"):
     266    assert (
     267        isinstance(contents, bytes) and "b" in mode or
     268        isinstance(contents, str) and "t" in mode or mode == ""), (type(contents), mode)
    256269    with open(target+".tmp", "w"+mode) as f:
    257270        f.write(contents)
     
    278291
    279292def precondition_abspath(path):
    280     if not isinstance(path, unicode):
     293    if not isinstance(path, str):
    281294        raise AssertionError("an abspath must be a Unicode string")
    282295
     
    310323    On Windows, the result will be a long path unless long_path is given as False.
    311324    """
    312     if not isinstance(path, unicode):
     325    if not isinstance(path, str):
    313326        raise AssertionError("paths must be Unicode strings")
    314327    if base is not None and long_path:
     
    331344    if not os.path.isabs(path):
    332345        if base is None:
    333             path = os.path.join(os.getcwdu(), path)
     346            cwd = os.getcwd()
     347            if PY2:
     348                cwd = cwd.decode('utf8')
     349            path = os.path.join(cwd, path)
    334350        else:
    335351            path = os.path.join(base, path)
     
    416432    # Based on <http://stackoverflow.com/questions/2608200/problems-with-umlauts-in-python-appdata-environvent-variable/2608368#2608368>,
    417433    # with improved error handling. Returns None if there is no enivronment variable of the given name.
    418     if not isinstance(name, unicode):
     434    if not isinstance(name, str):
    419435        raise AssertionError("name must be Unicode")
    420436
  • TabularUnified src/allmydata/util/statistics.py

    r1037854 r6e24def  
    2121    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
    2222
    23 from functools import reduce
    24 
    2523from allmydata.util.mathutil import round_sigfigs
    2624import math
     25from functools import reduce
    2726import sys
    2827
  • TabularUnified tox.ini

    r1037854 r6e24def  
    5151[testenv:py36]
    5252# On macOS, git inside of ratchet.sh needs $HOME.
    53 passenv = HOME
     53passenv = {[testenv]passenv} HOME
    5454commands = {toxinidir}/misc/python3/ratchet.sh
    5555
Note: See TracChangeset for help on using the changeset viewer.