1. 01 Oct, 2019 2 commits
    • Maxwell A McKinnon's avatar
      bpo-32689: Updates shutil.move to allow for Path objects to be used as source arg (GH-15326) · cf57cabe
      Maxwell A McKinnon authored
      
      
      Important work originally done by @emilyemorehouse two years ago and nearly ready to go in.
      
      This bug has affected many people and in some cases has been a dealbreaker to the adoption of the otherwise wonderful pathlib and PEP519. https://stackoverflow.com/questions/33625931/copy-file-with-pathlib-in-python.
      
      This adds the outstanding test request from that PR @vstinner (https://github.com/python/cpython/pull/5393).
      
      Test fails without the change, passes with it, along with every other test in test_shutil.
      
      Some variants were experimented with to make the one line change and the most performant one was picked.
      
      
      # Added Test for PathLike directory destination, the current fail case
      
      ```
      Lib/test/test_shutil.py::TestMove::test_move_file_pathlike FAILED                                                               [100%]
      
      ============================================================== FAILURES ===============================================================
      __________________________________________________ TestMove.test_move_file_pathlike ___________________________________________________
      
      self = <test.test_shutil.TestMove testMethod=test_move_file_pathlike>
      
          def test_move_file_pathlike(self):
              # Move a file to another location on the same filesystem.
              src = pathlib.Path(self.src_file)
      >       self._check_move_file(src, self.dst_dir, self.dst_file)
      
      Lib/test/test_shutil.py:1563:
      _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
      Lib/test/test_shutil.py:1545: in _check_move_file
          shutil.move(src, dst)
      /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/shutil.py:562: in move
          real_dst = os.path.join(dst, _basename(src))
      _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
      
      path = PosixPath('/var/folders/r2/psq74t5x3nbfzlph8bh2pvdw0000gn/T/tmp9ie0wh9_/foo')
      
          def _basename(path):
              # A basename() variant which first strips the trailing slash, if present.
              # Thus we always get the last component of the path, even for directories.
              sep = os.path.sep + (os.path.altsep or '')
      >       return os.path.basename(path.rstrip(sep))
      E       AttributeError: 'PosixPath' object has no attribute 'rstrip'
      
      /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/shutil.py:526: AttributeError
      ============================================== 1 failed, 102 deselected in 0.30 seconds ===============================================
      ```
      
      After change:
      
      ```
      ========================================================= test session starts =========================================================
      platform darwin -- Python 3.7.4, pytest-5.0.1, py-1.8.0, pluggy-0.12.0 -- /Users/maxwellmckinnon/.venvs/TA3.7/bin/python3.7
      cachedir: .pytest_cache
      rootdir: /Users/maxwellmckinnon/dev/cpython
      plugins: cov-2.7.1, mock-1.10.4
      collected 103 items / 102 deselected / 1 selected
      
      Lib/test/test_shutil.py::TestMove::test_move_file_pathlike PASSED                                                               [100%]
      
      ============================================== 1 passed, 102 deselected in 0.06 seconds ===============================================
      ```
      
      Running all the tests in test_shutil.py
      ```
      ╰─ pytest Lib/test/test_shutil.py -v
      ========================================================= test session starts =========================================================
      platform darwin -- Python 3.7.4, pytest-5.0.1, py-1.8.0, pluggy-0.12.0 -- /Users/maxwellmckinnon/.venvs/TA3.7/bin/python3.7
      cachedir: .pytest_cache
      rootdir: /Users/maxwellmckinnon/dev/cpython
      plugins: cov-2.7.1, mock-1.10.4
      collected 103 items
      
      Lib/test/test_shutil.py::TestShutil::test_chown PASSED                                                                          [  0%]
      Lib/test/test_shutil.py::TestShutil::test_copy PASSED                                                                           [  1%]
      ...
      Lib/test/test_shutil.py::TermsizeTests::test_stty_match SKIPPED                                                                 [ 99%]
      Lib/test/test_shutil.py::PublicAPITests::test_module_all_attribute PASSED                                                       [100%]
      
      ================================================ 96 passed, 7 skipped in 1.25 seconds =================================================
      ```
      
      # Performance Considerations
      Is it considered poor form to get rid of _basename altogether and make use of pathlib in the move function? I'm not sure if the idea is for all these modules to strictly avoid circular dependencies. They are already using os.path which is just as much a citizen in 3.8 as pathlib right?
      
      e.g.
      
      `real_dst = os.path.join(dst, _basename(src))`
      becomes
      `real_dst = Path(dst) / Path(src).name`
      
      I've looked around and familiarized myself, and I now think importing pathlib here is fine. My only remaining concern is that of performance.
      
      Here's the performance difference for this step. 
      
      ```
      In [46]: %timeit real_dst = os.path.join("a/b/c", _basename('b/'))
      2.71 µs ± 62.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
      
      In [47]: %timeit real_dst = Path("a/b/c") / Path('b/').name
      12.4 µs ± 65.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
      ```
      
      Is 10us significant or insignificant compared to the least expensive operation this function will do? I don't know. Let's find out.
      
      ```
      In [55]: %timeit os.rename('/tmp/a/a.txt', '/tmp/a/b.txt'); os.rename('/tmp/a/b.txt', '/tmp/a/a.txt')
      124 µs ± 2.18 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
      ```
      62us to rename. 10us seems significant enough that we wouldn't want to favor the Path sugar suggestion. 16% speed decrease from adding the 10us.
      
      What do people think? I was hoping to get to use pathlib.Path here, but I suspect for this low level move, it should be as fast as possible, and 16% is not worth one line of sugary code to me.
      
      
      
      https://bugs.python.org/issue32689
      
      
      
      Automerge-Triggered-By: @gvanrossum
      cf57cabe
    • Kyle Stanley's avatar
      e4070130
  2. 30 Sep, 2019 11 commits
  3. 29 Sep, 2019 4 commits
  4. 28 Sep, 2019 5 commits
    • Pascal Chambon's avatar
    • T. Wouters's avatar
      bpo-38115: Deal with invalid bytecode offsets in lnotab (GH-16079) · c8165036
      T. Wouters authored
      Document that lnotab can contain invalid bytecode offsets (because of
      terrible reasons that are difficult to fix). Make dis.findlinestarts()
      ignore invalid offsets in lnotab. All other uses of lnotab in CPython
      (various reimplementations of addr2line or line2addr in Python, C and gdb)
      already ignore this, because they take an address to look for, instead.
      
      Add tests for the result of dis.findlinestarts() on wacky constructs in
      test_peepholer.py, because it's the easiest place to add them.
      c8165036
    • Jason R. Coombs's avatar
      bpo-38216, bpo-36274: Allow subclasses to separately override validation and... · 7774d783
      Jason R. Coombs authored
      bpo-38216, bpo-36274: Allow subclasses to separately override validation and encoding behavior (GH-16448)
      
      * bpo-38216: Allow bypassing input validation
      
      * bpo-36274: Also allow the URL encoding to be overridden.
      
      * bpo-38216, bpo-36274: Add tests demonstrating a hook for overriding validation, test demonstrating override encoding, and a test to capture expectation of the interface for the URL.
      
      * Call with skip_host to avoid tripping on the host checking in the URL.
      
      * Remove obsolete comment.
      
      * Make _prepare_path_encoding its own attr.
      
      This makes overriding just that simpler.
      
      Also, don't use the := operator to make backporting easier.
      
      * Add a news entry.
      
      * _prepare_path_encoding -> _encode_prepared_path()
      
      * Once again separate the path validation and request encoding, drastically simplifying the behavior. Drop the guarantee that all processing happens in _prepare_path.
      7774d783
    • Victor Stinner's avatar
      bpo-38304: Add PyConfig.struct_size (GH-16451) · 441b10cf
      Victor Stinner authored
      Add a new struct_size field to PyPreConfig and PyConfig structures to
      allow to modify these structures in the future without breaking the
      backward compatibility.
      
      * Replace private _config_version field with public struct_size field
        in PyPreConfig and PyConfig.
      * Public PyPreConfig_InitIsolatedConfig() and
        PyPreConfig_InitPythonConfig()
        return type becomes PyStatus, instead of void.
      * Internal _PyConfig_InitCompatConfig(),
        _PyPreConfig_InitCompatConfig(), _PyPreConfig_InitFromConfig(),
        _PyPreConfig_InitFromPreConfig() return type becomes PyStatus,
        instead of void.
      * Remove _Py_CONFIG_VERSION
      * Update the Initialization Configuration documentation.
      441b10cf
    • Jesús Cea's avatar
  5. 27 Sep, 2019 7 commits
  6. 26 Sep, 2019 11 commits