From 0d5448090592fc54e470ab21c03a7864e66edd94 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 14 Jan 2022 16:59:12 +0000 Subject: Bump YouCompleteMe --- app-vim/youcompleteme/Manifest | 10 +- .../files/remove-python2-support.patch | 5309 -------------------- .../youcompleteme/youcompleteme-20200203-r5.ebuild | 118 - .../youcompleteme/youcompleteme-20220113.ebuild | 85 + 4 files changed, 88 insertions(+), 5434 deletions(-) delete mode 100644 app-vim/youcompleteme/files/remove-python2-support.patch delete mode 100644 app-vim/youcompleteme/youcompleteme-20200203-r5.ebuild create mode 100644 app-vim/youcompleteme/youcompleteme-20220113.ebuild (limited to 'app-vim/youcompleteme') diff --git a/app-vim/youcompleteme/Manifest b/app-vim/youcompleteme/Manifest index 07f7531..00e93aa 100644 --- a/app-vim/youcompleteme/Manifest +++ b/app-vim/youcompleteme/Manifest @@ -1,7 +1,3 @@ -AUX remove-python2-support.patch 199204 BLAKE2B 570bd01ae3e8a89c367194329f09738748a64b88b958dc085f91ff42a3a2f1751194905658c8b1d7ff5362869280952d9fec3ed022a0377a2399422e9b25fd70 SHA512 afccbce17d4f5a6605e11c4af65f2f3f89fd70aa689cfd9bfa4aceb08414f0b66ba822d362183499dda42f35996ebc15b478d8bdb348de21a1ad8ccb4651592d -DIST gocode-5bee97b488366fd20b054d0861b89834ff5bbfb2.tar.gz 97152 BLAKE2B 4d5e4e6c2cc46348def3cc7700c47f73ac678ce31671d41d4ce37942477a66a65160a2c9d4fb4c6431d46ed2937d67290a6e6565e73b973862da431cbb281ba7 SHA512 9b1e81635a0b168d6e242afb69c47ec95ea9ccca3b039f54193591e9ea2bf09c914765bbf989adfa0ac55e3aab4007eae5fcee8ab28fe695ef87be71a884a4d6 -DIST omnisharp-server-e1902915c6790bcec00b8d551199c8a3537d33c9.tar.gz 3005049 BLAKE2B 07c7a06c3d2b75a6df7b6bc6e2e26dc1dbab1af1e98018db14177a82304eb48160bb4dd25f0d6d1af5a50725e6d1b8365932a5ff575d2c08be87997f2ee58397 SHA512 47b6083016d9865708b3deaf44f3742f276d5aa13c3a310b9aa432650df18d35bed62668a90f1aba52fbe84fb7471dd885c34e351b859607d7221ae074290fde -DIST requests-futures-148451a06781d8196e5fb7e0e2bca7a765368ff1.tar.gz 7823 BLAKE2B 6ae2d74849f99a44a449caff70f065d8548d773224b39da661edb880a4eb84aa97da62bd72178b8713cb58ec5deb599fa7eb371fe90669fafc1e42611ada31d1 SHA512 396b02c202f0aa748df02afd8d04b72a2426932e55dde599a82fe134aa585b105267299899c12577f82d43479c56b95d257476010b8d7808817705c1e94a1781 -DIST ycmd-d3378ca3a3103535c14b104cb916dcbcdaf93eeb.tar.gz 4504015 BLAKE2B f79a3616c9ea2789cd10dd7e1d2b60d651c1f592b213cc0806f92ba12a115ddb3408ac7565e9e486c827ee87a8d4518c55a029f73d518749d3cfa0cd01cd5f00 SHA512 c4af6810995262a5c145ca8eeed9bf92c6ac204ac507f27571b68ed3258affae5734b5edfccdc6ae5f7fa310e1dbf9f74f2681d9c6d774685469ee314ada2573 -DIST youcompleteme-124661f218e80b96c1f9f3d124e99f9a2fd2d83b.tar.gz 317144 BLAKE2B 6fc1d421a41e13923dd677deeabda9b5350c526558acae53d1e38eba4f911ba8d99c28f9b60fcbadd36452fdf985e1c01d456d14ffdb6e86c4bd3fcf38567939 SHA512 7442ad4b72f7782f055ae9ed9e94221a579448f3aaf7054246218e50ab0b19a4f451239a0c67e3c59c27e6e9d8a005273d8524f1acc8f1f855eb14c1b0731078 -EBUILD youcompleteme-20200203-r5.ebuild 3707 BLAKE2B 3f0705a744db402374e669e87b4bc690488fbf54219d81d6a003ed8c6f19a556d51fbfebac27376677482ab17aa900d2afe394b615d5279428707959a9b01dc4 SHA512 ee66a1e9cd8ccd790107871a1dd9161d9881d9228a0c31144d6bba6f14be33fcfc00ed67d79e881bc8616fcc9f5839e03526646b622e9a1ddef27d65dbd08092 +DIST ycmd-f7ba6e791829c2ad0a3b77bd8e921f2b4c71d7dc.tar.gz 2953797 BLAKE2B e56b17c3f9b714eda7a7405c44330b651f578b4d5a5799f0fde0d2a1661d7e513f5265c839c6afa1959188e8c339c8064c58ec7dea35b24872b4b08780f2dd04 SHA512 479a2843904910f150303101843414e9290c279c87e1410665fd84d5e9895e194832d461bae0ef6a7893a2c87df09049405d2a4d36a4a96c115f371e27b82d24 +DIST youcompleteme-7684b6c6b49f8d3bdbd17ecdc9ee7d228039808e.tar.gz 305508 BLAKE2B 9e5f6cae9d288e2b24e503b8df11928dc5cbeaada6b4f24bab0ed93aeb7705ab4b1312e4000091b77eb47561d7cd9b9ffd2442086b57c22fd6dace246ea83a16 SHA512 91a0f004adc371750702af87715e396d885507cf84a9f6120c1f6a865bedc520e7918697d8bdcf1fd6096c7fc32accb7f6f62a60b6c074a3b6089058f6d1ed62 +EBUILD youcompleteme-20220113.ebuild 2422 BLAKE2B c2c795e6ac1af250e5e70d36d89fe4493c6e4da263d1076dece7a54e14bc9db077850b89cbce11eee39d8e63f0d9d3c42952c8c40a3bef0595bb623d37206c18 SHA512 b3db2f11ffe6fa2a87d1ebe885c90dc98830cb3b851f79bc7d0908235b0db2761f27aa3ecac6b8bc0af47f81d4948f9d0a115cf664ee32ab97abd6b80639c71d diff --git a/app-vim/youcompleteme/files/remove-python2-support.patch b/app-vim/youcompleteme/files/remove-python2-support.patch deleted file mode 100644 index 08cbb74..0000000 --- a/app-vim/youcompleteme/files/remove-python2-support.patch +++ /dev/null @@ -1,5309 +0,0 @@ -From db57ade716d366e92c604b6d385c96c4b8db8a65 Mon Sep 17 00:00:00 2001 -From: Boris Staletic -Date: Thu, 21 Nov 2019 12:58:02 +0100 -Subject: [PATCH] Remove python2 support - ---- - README.md | 90 +-- - autoload/youcompleteme.vim | 194 ++--- - azure-pipelines.yml | 13 - - install.sh | 11 +- - plugin/youcompleteme.vim | 8 +- - python/ycm/base.py | 7 - - python/ycm/buffer.py | 9 +- - python/ycm/client/base_request.py | 20 +- - python/ycm/client/command_request.py | 7 - - .../ycm/client/completer_available_request.py | 7 - - python/ycm/client/completion_request.py | 7 - - python/ycm/client/debug_info_request.py | 7 - - python/ycm/client/event_notification.py | 7 - - python/ycm/client/messages_request.py | 7 - - python/ycm/client/omni_completion_request.py | 7 - - python/ycm/client/shutdown_request.py | 7 - - python/ycm/client/signature_help_request.py | 7 - - python/ycm/client/ycmd_keepalive.py | 9 +- - python/ycm/diagnostic_filter.py | 16 +- - python/ycm/diagnostic_interface.py | 18 +- - python/ycm/omni_completer.py | 7 - - python/ycm/paths.py | 28 +- - python/ycm/signature_help.py | 9 +- - python/ycm/syntax_parse.py | 12 +- - python/ycm/tests/__init__.py | 7 - - python/ycm/tests/base_test.py | 11 +- - python/ycm/tests/client/base_request_test.py | 7 - - .../ycm/tests/client/command_request_test.py | 11 +- - .../tests/client/completion_request_test.py | 9 +- - .../tests/client/debug_info_request_test.py | 7 - - .../ycm/tests/client/messages_request_test.py | 8 - - .../client/omni_completion_request_tests.py | 7 - - python/ycm/tests/command_test.py | 7 - - python/ycm/tests/completion_test.py | 9 - - python/ycm/tests/diagnostic_filter_test.py | 7 - - python/ycm/tests/event_notification_test.py | 9 - - python/ycm/tests/mock_utils.py | 11 +- - python/ycm/tests/paths_test.py | 23 +- - python/ycm/tests/postcomplete_test.py | 7 - - python/ycm/tests/signature_help_test.py | 9 - - python/ycm/tests/syntax_parse_test.py | 7 - - python/ycm/tests/test_utils.py | 48 +- - python/ycm/tests/vimsupport_test.py | 12 - - python/ycm/tests/youcompleteme_test.py | 33 +- - python/ycm/unsafe_thread_pool_executor.py | 3 +- - python/ycm/vimsupport.py | 16 +- - python/ycm/youcompleteme.py | 34 +- - test/README.md | 8 +- - test/docker/ci/push | 1 - - test/docker/ci/rebuild | 3 - - test/docker/manual/push | 1 - - test/docker/manual/rebuild | 3 - - third_party/pythonfutures/CHANGES | 44 -- - third_party/pythonfutures/LICENSE | 21 - - .../pythonfutures/concurrent/__init__.py | 3 - - .../concurrent/futures/__init__.py | 18 - - .../pythonfutures/concurrent/futures/_base.py | 574 -------------- - .../concurrent/futures/_compat.py | 101 --- - .../concurrent/futures/process.py | 363 --------- - .../concurrent/futures/thread.py | 138 ---- - third_party/pythonfutures/crawl.py | 74 -- - third_party/pythonfutures/docs/conf.py | 194 ----- - third_party/pythonfutures/docs/index.rst | 345 --------- - third_party/pythonfutures/docs/make.bat | 112 --- - third_party/pythonfutures/futures/__init__.py | 24 - - third_party/pythonfutures/futures/process.py | 1 - - third_party/pythonfutures/futures/thread.py | 1 - - third_party/pythonfutures/primes.py | 50 -- - third_party/pythonfutures/setup.cfg | 6 - - third_party/pythonfutures/setup.py | 33 - - third_party/pythonfutures/test_futures.py | 723 ------------------ - third_party/pythonfutures/tox.ini | 8 - - 75 files changed, 183 insertions(+), 3552 deletions(-) - delete mode 100755 third_party/pythonfutures/CHANGES - delete mode 100755 third_party/pythonfutures/LICENSE - delete mode 100755 third_party/pythonfutures/concurrent/__init__.py - delete mode 100755 third_party/pythonfutures/concurrent/futures/__init__.py - delete mode 100755 third_party/pythonfutures/concurrent/futures/_base.py - delete mode 100755 third_party/pythonfutures/concurrent/futures/_compat.py - delete mode 100755 third_party/pythonfutures/concurrent/futures/process.py - delete mode 100755 third_party/pythonfutures/concurrent/futures/thread.py - delete mode 100755 third_party/pythonfutures/crawl.py - delete mode 100755 third_party/pythonfutures/docs/conf.py - delete mode 100755 third_party/pythonfutures/docs/index.rst - delete mode 100755 third_party/pythonfutures/docs/make.bat - delete mode 100755 third_party/pythonfutures/futures/__init__.py - delete mode 100755 third_party/pythonfutures/futures/process.py - delete mode 100755 third_party/pythonfutures/futures/thread.py - delete mode 100755 third_party/pythonfutures/primes.py - delete mode 100755 third_party/pythonfutures/setup.cfg - delete mode 100755 third_party/pythonfutures/setup.py - delete mode 100755 third_party/pythonfutures/test_futures.py - delete mode 100755 third_party/pythonfutures/tox.ini - -diff --git a/README.md b/README.md -index d296b5ba3..0705acdb2 100644 ---- a/README.md -+++ b/README.md -@@ -281,7 +281,7 @@ YouCompleteMe, however they may not work for everyone. If the following - instructions don't work for you, check out the [full installation - guide](#full-installation-guide). - --Make sure you have Vim 7.4.1578 with Python 2 or Python 3 support. The Vim -+Make sure you have Vim 7.4.1578 with Python 3 support. The Vim - package on Fedora 27 and later and the pre-installed Vim on Ubuntu 16.04 and - later are recent enough. You can see the version of Vim installed by running - `vim --version`. If the version is too old, you may need to [compile Vim from -@@ -376,13 +376,13 @@ guide](#full-installation-guide). - **Important:** we assume that you are using the `cmd.exe` command prompt and - that you know how to add an executable to the PATH environment variable. - --Make sure you have at least Vim 7.4.1578 with Python 2 or Python 3 support. You -+Make sure you have at least Vim 7.4.1578 with Python 3 support. You - can check the version and which Python is supported by typing `:version` inside --Vim. Look at the features included: `+python/dyn` for Python 2 and --`+python3/dyn` for Python 3. Take note of the Vim architecture, i.e. 32 or -+Vim. Look at the features included: `+python3/dyn` for Python 3. -+Take note of the Vim architecture, i.e. 32 or - 64-bit. It will be important when choosing the Python installer. We recommend - using a 64-bit client. [Daily updated installers of 32-bit and 64-bit Vim with --Python 2 and Python 3 support][vim-win-download] are available. -+Python 3 support][vim-win-download] are available. - - **NOTE**: For all features, such as signature help, use Vim 8.1.1875 or later. - -@@ -403,17 +403,15 @@ process. - - Download and install the following software: - --- [Python 2 or Python 3][python-win-download]. Be sure to pick the version -+- [Python 3][python-win-download]. Be sure to pick the version - corresponding to your Vim architecture. It is _Windows x86_ for a 32-bit Vim - and _Windows x86-64_ for a 64-bit Vim. We recommend installing Python 3. - Additionally, the version of Python you install must match up exactly with - the version of Python that Vim is looking for. Type `:version` and look at the - bottom of the page at the list of compiler flags. Look for flags that look -- similar to `-DDYNAMIC_PYTHON_DLL=\"python27.dll\"` and -- `-DDYNAMIC_PYTHON3_DLL=\"python35.dll\"`. The former indicates that Vim is -- looking for Python 2.7 and the latter indicates that Vim is looking for -- Python 3.5. You'll need one or the other installed, matching the version -- number exactly. -+ similar to `-DDYNAMIC_PYTHON3_DLL=\"python35.dll\"`. This indicates -+ that Vim is looking for Python 3.5. You'll need one or the other installed, -+ matching the version number exactly. - - [CMake][cmake-download]. Add CMake executable to the PATH environment - variable. - - [Visual Studio Build Tools 2017][visual-studio-download]. During setup, -@@ -488,7 +486,7 @@ guide](#full-installation-guide). - - **NOTE:** OpenBSD / FreeBSD are not officially supported platforms by YCM. - --Make sure you have Vim 7.4.1578 with Python 2 or Python 3 support. -+Make sure you have Vim 7.4.1578 with Python 3 support. - - **NOTE**: For all features, such as signature help, use Vim 8.1.1875 or later. - -@@ -588,7 +586,7 @@ process. - **Please follow the instructions carefully. Read EVERY WORD.** - - 1. **Ensure that your version of Vim is _at least_ 7.4.1578 _and_ that it has -- support for Python 2 or Python 3 scripting**. -+ support for Python 3 scripting**. - - Inside Vim, type `:version`. Look at the first two to three lines of output; - it should say `Vi IMproved X.Y`, where X.Y is the major version of vim. If -@@ -654,7 +652,7 @@ process. - Debian-like Linux distro, this would be `sudo apt-get install python-dev - python3-dev`. On macOS they should already be present. - -- On Windows, you need to download and install [Python 2 or -+ On Windows, you need to download and install [Python - Python 3][python-win-download]. Pick the version corresponding to your Vim - architecture. You will also need Microsoft Visual C++ (MSVC) to build YCM. - You can obtain it by installing [Visual Studio Build -@@ -1500,8 +1498,6 @@ should work out of the box with no additional configuration (provided that you - built YCM with the `--rust-completer` flag; see the [*Installation* - section](#installation) for details). The install script takes care of - installing [the Rust source code][rust-src], so no configuration is necessary. --In case you are running Python 2.7.8 and older, you will need to manually --install [rustup][]. - - To [configure RLS](#lsp-configuration) look up [rls configuration options][ - rls-preferences] -@@ -3252,34 +3248,6 @@ But fear not, you should be able to tweak your extra conf files to continue - working by using the `g:ycm_extra_conf_vim_data` option. See the docs on that - option for details. - --### I get `ImportError` exceptions that mention `PyInit_ycm_core` or `initycm_core` -- --These errors are caused by building the YCM native libraries for Python 2 and --trying to load them into a Python 3 process (or the other way around). -- --For instance, if building for Python 2 but loading in Python 3: -- --``` --ImportError: dynamic module does not define init function (PyInit_ycm_core) --``` -- --If building for Python 3 but loading in Python 2: -- --``` --ImportError: dynamic module does not define init function (initycm_core) --``` -- --Setting the `g:ycm_server_python_interpreter` option to force the use of a --specific Python interpreter for `ycmd` is usually the easiest way to solve the --problem. Common values for that option are `/usr/bin/python` and --`/usr/bin/python3`. -- --### I get a linker warning regarding `libpython` on macOS when compiling YCM -- --If the warning is `ld: warning: path '/usr/lib/libpython2.7.dylib' following -L --not a directory`, then feel free to ignore it; it's caused by a limitation of --CMake and is not an issue. Everything should still work fine. -- - ### I get a weird window at the top of my file when I use the semantic engine - - This is Vim's `preview` window. Vim uses it to show you extra information about -@@ -3357,20 +3325,20 @@ Look at the output of your CMake call. There should be a line in it like the - following (with `.dylib` in place of `.so` on macOS): - - ``` ---- Found PythonLibs: /usr/lib/libpython2.7.so (Required is at least version "2.5") -+-- Found PythonLibs: /usr/lib/libpython3.6.so (Required is at least version "3.5") - ``` - - That would be the **correct** output. An example of **incorrect** output would - be the following: - - ``` ---- Found PythonLibs: /usr/lib/libpython2.7.so (found suitable version "2.5.1", minimum required is "2.5") -+-- Found PythonLibs: /usr/lib/libpython3.6.so (found suitable version "3.5.1", minimum required is "3.5") - ``` - - Notice how there's an extra bit of output there, the `found suitable version - ""` part, where `` is not the same as the version of the --dynamic library. In the example shown, the library is version 2.7 but the second --string is version `2.5.1`. -+dynamic library. In the example shown, the library is version 3.6 but the second -+string is version `3.5.1`. - - This means that CMake found one version of Python headers and a different - version for the library. This is wrong. It can happen when you have multiple -@@ -3380,7 +3348,7 @@ You should probably add the following flags to your cmake call (again, `dylib` - instead of `so` on macOS): - - ``` ---DPYTHON_INCLUDE_DIR=/usr/include/python2.7 -DPYTHON_LIBRARY=/usr/lib/libpython2.7.so -+-DPYTHON_INCLUDE_DIR=/usr/include/python3.6 -DPYTHON_LIBRARY=/usr/lib/libpython3.6.so - ``` - - This will force the paths to the Python include directory and the Python library -@@ -3388,22 +3356,22 @@ to use. You may need to set these flags to something else, but you need to make - sure you use the same version of Python that your Vim binary is built against, - which is highly likely to be the system's default Python. - --### I get `libpython2.7.a [...] relocation R_X86_64_32` when compiling -+### I get `libpython3.5.a [...] relocation R_X86_64_32` when compiling - - The error is usually encountered when compiling YCM on Centos or RHEL. The full - error looks something like the following: - - ``` --/usr/bin/ld: /usr/local/lib/libpython2.7.a(abstract.o): relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC -+/usr/bin/ld: /usr/local/lib/libpython3.5.a(abstract.o): relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC - ``` - - It's possible to get a slightly different error that's similar to the one above. - Here's the problem and how you solve it: - --Your `libpython2.7.a` was not compiled with `-fPIC` so it can't be linked into -+Your `libpython3.5.a` was not compiled with `-fPIC` so it can't be linked into - `ycm_core.so`. Use the `-DPYTHON_LIBRARY=` CMake flag to point it to a `.so` - version of libpython on your machine (for instance, --`-DPYTHON_LIBRARY=/usr/lib/libpython2.7.so`). Naturally, this means you'll have -+`-DPYTHON_LIBRARY=/usr/lib/libpython3.5.so`). Naturally, this means you'll have - to go through the full installation guide by hand. - - ### I see `undefined symbol: clang_getCompletionFixIt` in the server logs. -@@ -3640,20 +3608,6 @@ os.environ['PATH'] = ';'.join(path) - EOF - ``` - --### I hear that YCM only supports Python 2, is that true? -- --**No.** Both the Vim client and the [ycmd server][ycmd] run on Python 2 or 3. If --you are talking about code completion in a project, you can configure the Python --used for your project through a `.ycm_extra_conf.py` file. See [the Python --Semantic Completion section](#python-semantic-completion) for more details. -- --### On Windows I get `E887: Sorry, this command is disabled, the Python's site module could not be loaded` -- --If you are running vim on Windows with Python 2.7.11, this is likely caused by a --[bug][vim_win-python2.7.11-bug]. Follow this --[workaround][vim_win-python2.7.11-bug_workaround] or use a different version --(Python 2.7.12 does not suffer from the bug). -- - ### I can't complete Python packages in a virtual environment. - - This means that the Python used to run [Jedi][] is not the Python of the virtual -@@ -3823,8 +3777,6 @@ This software is licensed under the [GPL v3 license][gpl]. - [add-msbuild-to-path]: http://stackoverflow.com/questions/6319274/how-do-i-run-msbuild-from-the-command-line-using-windows-sdk-7-1 - [identify-R6034-cause]: http://stackoverflow.com/questions/14552348/runtime-error-r6034-in-embedded-python-application/34696022 - [ccoc]: https://github.com/Valloric/YouCompleteMe/blob/master/CODE_OF_CONDUCT.md --[vim_win-python2.7.11-bug]: https://github.com/vim/vim/issues/717 --[vim_win-python2.7.11-bug_workaround]: https://github.com/vim/vim-win32-installer/blob/a27bbdba9bb87fa0e44c8a00d33d46be936822dd/appveyor.bat#L86-L88 - [gitter]: https://gitter.im/Valloric/YouCompleteMe - [ninja-compdb]: https://ninja-build.org/manual.html - [++enc]: http://vimdoc.sourceforge.net/htmldoc/editing.html#++enc -diff --git a/autoload/youcompleteme.vim b/autoload/youcompleteme.vim -index d8f4703e5..8e07aa8e7 100644 ---- a/autoload/youcompleteme.vim -+++ b/autoload/youcompleteme.vim -@@ -58,32 +58,6 @@ let s:buftype_blacklist = { - \ } - - --" When both versions are available, we prefer Python 3 over Python 2: --" - faster startup (no monkey-patching from python-future); --" - better Windows support (e.g. temporary paths are not returned in all --" lowercase); --" - Python 2 support will eventually be dropped. --function! s:UsingPython3() -- if has('python3') -- return 1 -- endif -- return 0 --endfunction -- -- --let s:using_python3 = s:UsingPython3() --let s:python_until_eof = s:using_python3 ? "python3 << EOF" : "python << EOF" --let s:python_command = s:using_python3 ? "py3 " : "py " -- -- --function! s:Pyeval( eval_string ) -- if s:using_python3 -- return py3eval( a:eval_string ) -- endif -- return pyeval( a:eval_string ) --endfunction -- -- - function! s:StartMessagePoll() - if s:pollers.receive_messages.id < 0 - let s:pollers.receive_messages.id = timer_start( -@@ -96,10 +70,9 @@ endfunction - function! s:ReceiveMessages( timer_id ) - let poll_again = v:false - if s:AllowedToCompleteInCurrentBuffer() -- let poll_again = s:Pyeval( 'ycm_state.OnPeriodicTick()' ) -+ let poll_again = py3eval( 'ycm_state.OnPeriodicTick()' ) - endif - -- - if poll_again - let s:pollers.receive_messages.id = timer_start( - \ s:pollers.receive_messages.wait_milliseconds, -@@ -164,7 +137,7 @@ function! youcompleteme#Enable() - \ s:pollers.server_ready.wait_milliseconds, - \ function( 's:PollServerReady' ) ) - -- let s:default_completion = s:Pyeval( 'vimsupport.NO_COMPLETIONS' ) -+ let s:default_completion = py3eval( 'vimsupport.NO_COMPLETIONS' ) - let s:completion = s:default_completion - - if exists( '*prop_type_add' ) && exists( '*prop_type_delete' ) -@@ -198,50 +171,24 @@ endfunction - - - function! youcompleteme#GetErrorCount() -- return s:Pyeval( 'ycm_state.GetErrorCount()' ) -+ return py3eval( 'ycm_state.GetErrorCount()' ) - endfunction - - - function! youcompleteme#GetWarningCount() -- return s:Pyeval( 'ycm_state.GetWarningCount()' ) -+ return py3eval( 'ycm_state.GetWarningCount()' ) - endfunction - - - function! s:SetUpPython() abort -- exec s:python_until_eof --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import -- -+ py3 << EOF - import os.path as p --import re - import sys - import traceback - import vim - - root_folder = p.normpath( p.join( vim.eval( 's:script_folder_path' ), '..' ) ) - third_party_folder = p.join( root_folder, 'third_party' ) --python_stdlib_zip_regex = re.compile( 'python[23][0-9]\\.zip' ) -- -- --def IsStandardLibraryFolder( path ): -- return ( ( p.isfile( path ) -- and python_stdlib_zip_regex.match( p.basename( path ) ) ) -- or p.isfile( p.join( path, 'os.py' ) ) ) -- -- --def IsVirtualEnvLibraryFolder( path ): -- return p.isfile( p.join( path, 'orig-prefix.txt' ) ) -- -- --def GetStandardLibraryIndexInSysPath(): -- for index, path in enumerate( sys.path ): -- if ( IsStandardLibraryFolder( path ) and -- not IsVirtualEnvLibraryFolder( path ) ): -- return index -- raise RuntimeError( 'Could not find standard library path in Python path.' ) -- - - # Add dependencies to Python path. - dependencies = [ p.join( root_folder, 'python' ), -@@ -256,18 +203,10 @@ dependencies = [ p.join( root_folder, 'python' ), - p.join( third_party_folder, 'requests_deps', 'certifi' ), - p.join( third_party_folder, 'requests_deps', 'requests' ) ] - --# The concurrent.futures module is part of the standard library on Python 3. --if sys.version_info[ 0 ] == 2: -- dependencies.append( p.join( third_party_folder, 'pythonfutures' ) ) -- - sys.path[ 0:0 ] = dependencies - - # We enclose this code in a try/except block to avoid backtraces in Vim. - try: -- # The python-future module must be inserted after the standard library path. -- sys.path.insert( GetStandardLibraryIndexInSysPath() + 1, -- p.join( third_party_folder, 'python-future', 'src' ) ) -- - # Import the modules used in this file. - from ycm import base, vimsupport, youcompleteme - -@@ -315,14 +254,12 @@ function! s:SetUpKeyMappings() - " With this command, when the completion window is visible, the tab key - " (default) will select the next candidate in the window. In vim, this also - " changes the typed-in text to that of the candidate completion. -- exe 'inoremap ' . key . -- \ ' pumvisible() ? "\" : "\' . key .'"' -+ exe 'inoremap ' . key . ' pumvisible() ? "\" : "\' . key .'"' - endfor - - for key in g:ycm_key_list_previous_completion - " This selects the previous candidate for shift-tab (default) -- exe 'inoremap ' . key . -- \ ' pumvisible() ? "\" : "\' . key .'"' -+ exe 'inoremap ' . key . ' pumvisible() ? "\" : "\' . key .'"' - endfor - - for key in g:ycm_key_list_stop_completion -@@ -387,10 +324,12 @@ function! s:SetUpSigns() - highlight link YcmWarningLine SyntasticWarningLine - endif - -- exe 'sign define YcmError text=' . g:ycm_error_symbol . -- \ ' texthl=YcmErrorSign linehl=YcmErrorLine' -- exe 'sign define YcmWarning text=' . g:ycm_warning_symbol . -- \ ' texthl=YcmWarningSign linehl=YcmWarningLine' -+ call sign_define( 'YcmError', { 'text': g:ycm_error_symbol, -+ \ 'texthl': 'YcmErrorSign', -+ \ 'linehl': 'YcmErrorLine' } ) -+ call sign_define( 'YcmWarning', { 'text': g:ycm_error_symbol, -+ \ 'texthl': 'YcmWarningSign', -+ \ 'linehl': 'YcmWarningLine' } ) - endfunction - - -@@ -451,9 +390,8 @@ function! s:DisableOnLargeFile( buffer ) - let b:ycm_largefile = - \ threshold > 0 && getfsize( expand( a:buffer ) ) > threshold - if b:ycm_largefile -- exec s:python_command "vimsupport.PostVimMessage(" . -- \ "'YouCompleteMe is disabled in this buffer; " . -- \ "the file exceeded the max size (see YCM options).' )" -+ py3 vimsupport.PostVimMessage( 'YouCompleteMe is disabled in this buffer;' . -+ \ ' the file exceeded the max size (see YCM options).' ) - endif - return b:ycm_largefile - endfunction -@@ -560,7 +498,7 @@ function! s:OnVimLeave() - for poller in values( s:pollers ) - call s:StopPoller( poller ) - endfor -- exec s:python_command "ycm_state.OnVimLeave()" -+ py3 ycm_state.OnVimLeave() - endfunction - - -@@ -569,7 +507,7 @@ function! s:OnCompleteDone() - return - endif - -- exec s:python_command "ycm_state.OnCompleteDone()" -+ py3 ycm_state.OnCompleteDone() - call s:UpdateSignatureHelp() - endfunction - -@@ -599,7 +537,7 @@ function! s:OnFileTypeSet() - call s:SetCompleteFunc() - call s:StartMessagePoll() - -- exec s:python_command "ycm_state.OnFileTypeSet()" -+ py3 ycm_state.OnFileTypeSet() - call s:OnFileReadyToParse( 1 ) - endfunction - -@@ -613,7 +551,7 @@ function! s:OnBufferEnter() - call s:SetUpCompleteopt() - call s:SetCompleteFunc() - -- exec s:python_command "ycm_state.OnBufferVisit()" -+ py3 ycm_state.OnBufferVisit() - " Last parse may be outdated because of changes from other buffers. Force a - " new parse. - call s:OnFileReadyToParse( 1 ) -@@ -628,23 +566,23 @@ function! s:OnBufferUnload() - return - endif - -- exec s:python_command "ycm_state.OnBufferUnload( " . buffer_number . " )" -+ py3 ycm_state.OnBufferUnload( vimsupport.GetIntValue( 'buffer_number' ) ) - endfunction - - - function! s:UpdateMatches() -- exec s:python_command "ycm_state.UpdateMatches()" -+ py3 ycm_state.UpdateMatches() - endfunction - - - function! s:PollServerReady( timer_id ) -- if !s:Pyeval( 'ycm_state.IsServerAlive()' ) -- exec s:python_command "ycm_state.NotifyUserIfServerCrashed()" -+ if !py3eval( 'ycm_state.IsServerAlive()' ) -+ py3 ycm_state.NotifyUserIfServerCrashed() - " Server crashed. Don't poll it again. - return - endif - -- if !s:Pyeval( 'ycm_state.CheckIfServerIsReady()' ) -+ if !py3eval( 'ycm_state.CheckIfServerIsReady()' ) - let s:pollers.server_ready.id = timer_start( - \ s:pollers.server_ready.wait_milliseconds, - \ function( 's:PollServerReady' ) ) -@@ -663,11 +601,11 @@ function! s:OnFileReadyToParse( ... ) - - " We only want to send a new FileReadyToParse event notification if the buffer - " has changed since the last time we sent one, or if forced. -- if force_parsing || s:Pyeval( "ycm_state.NeedsReparse()" ) -+ if force_parsing || py3eval( "ycm_state.NeedsReparse()" ) - " We switched buffers or somethuing, so claer. - " FIXME: sig hekp should be buffer local? - call s:ClearSignatureHelp() -- exec s:python_command "ycm_state.OnFileReadyToParse()" -+ py3 ycm_state.OnFileReadyToParse() - - call s:StopPoller( s:pollers.file_parse_response ) - let s:pollers.file_parse_response.id = timer_start( -@@ -678,15 +616,15 @@ endfunction - - - function! s:PollFileParseResponse( ... ) -- if !s:Pyeval( "ycm_state.FileParseRequestReady()" ) -+ if !py3eval( "ycm_state.FileParseRequestReady()" ) - let s:pollers.file_parse_response.id = timer_start( - \ s:pollers.file_parse_response.wait_milliseconds, - \ function( 's:PollFileParseResponse' ) ) - return - endif - -- exec s:python_command "ycm_state.HandleFileParseRequest()" -- if s:Pyeval( "ycm_state.ShouldResendFileParseRequest()" ) -+ py3 ycm_state.HandleFileParseRequest() -+ if py3eval( "ycm_state.ShouldResendFileParseRequest()" ) - call s:OnFileReadyToParse( 1 ) - endif - endfunction -@@ -755,7 +693,7 @@ function! s:OnCursorMovedNormalMode() - return - endif - -- exec s:python_command "ycm_state.OnCursorMoved()" -+ py3 ycm_state.OnCursorMoved() - endfunction - - -@@ -784,7 +722,7 @@ function! s:OnTextChangedInsertMode() - " We have to make sure we correctly leave semantic mode even when the user - " inserts something like a "operator[]" candidate string which fails - " CurrentIdentifierFinished check. -- if s:force_semantic && !s:Pyeval( 'base.LastEnteredCharIsIdentifierChar()' ) -+ if s:force_semantic && !py3eval( 'base.LastEnteredCharIsIdentifierChar()' ) - let s:force_semantic = 0 - endif - -@@ -800,7 +738,7 @@ function! s:OnTextChangedInsertMode() - call s:RequestSignatureHelp() - endif - -- exec s:python_command "ycm_state.OnCursorMoved()" -+ py3 ycm_state.OnCursorMoved() - - if g:ycm_autoclose_preview_window_after_completion - call s:ClosePreviewWindowIfNeeded() -@@ -818,7 +756,7 @@ function! s:OnInsertLeave() - let s:completion = s:default_completion - - call s:OnFileReadyToParse() -- exec s:python_command "ycm_state.OnInsertLeave()" -+ py3 ycm_state.OnInsertLeave() - if g:ycm_autoclose_preview_window_after_completion || - \ g:ycm_autoclose_preview_window_after_insertion - call s:ClosePreviewWindowIfNeeded() -@@ -845,10 +783,10 @@ endfunction - - - function! s:IdentifierFinishedOperations() -- if !s:Pyeval( 'base.CurrentIdentifierFinished()' ) -+ if !py3eval( 'base.CurrentIdentifierFinished()' ) - return - endif -- exec s:python_command "ycm_state.OnCurrentIdentifierFinished()" -+ py3 ycm_state.OnCurrentIdentifierFinished() - let s:force_semantic = 0 - let s:completion = s:default_completion - endfunction -@@ -888,13 +826,13 @@ endfunction - - - function! s:OnBlankLine() -- return s:Pyeval( 'not vim.current.line or vim.current.line.isspace()' ) -+ return py3eval( 'not vim.current.line or vim.current.line.isspace()' ) - endfunction - - - function! s:RequestCompletion() -- exec s:python_command "ycm_state.SendCompletionRequest(" . -- \ "vimsupport.GetBoolValue( 's:force_semantic' ) )" -+ py3 ycm_state.SendCompletionRequest( -+ \ vimsupport.GetBoolValue( 's:force_semantic' ) ) - - call s:PollCompletion() - endfunction -@@ -903,7 +841,7 @@ endfunction - function! s:RequestSemanticCompletion() - if &completefunc == "youcompleteme#CompleteFunc" - let s:force_semantic = 1 -- exec s:python_command "ycm_state.SendCompletionRequest( True )" -+ py3 ycm_state.SendCompletionRequest( True ) - - call s:PollCompletion() - endif -@@ -916,20 +854,20 @@ endfunction - - - function! s:PollCompletion( ... ) -- if !s:Pyeval( 'ycm_state.CompletionRequestReady()' ) -+ if !py3eval( 'ycm_state.CompletionRequestReady()' ) - let s:pollers.completion.id = timer_start( - \ s:pollers.completion.wait_milliseconds, - \ function( 's:PollCompletion' ) ) - return - endif - -- let s:completion = s:Pyeval( 'ycm_state.GetCompletionResponse()' ) -+ let s:completion = py3eval( 'ycm_state.GetCompletionResponse()' ) - call s:Complete() - endfunction - - - function! s:ShouldUseSignatureHelp() -- return s:Pyeval( 'vimsupport.VimSupportsPopupWindows()' ) -+ return py3eval( 'vimsupport.VimSupportsPopupWindows()' ) - endfunction - - -@@ -943,7 +881,7 @@ function! s:RequestSignatureHelp() - return - endif - -- if s:Pyeval( 'ycm_state.SendSignatureHelpRequest()' ) -+ if py3eval( 'ycm_state.SendSignatureHelpRequest()' ) - call s:PollSignatureHelp() - endif - endfunction -@@ -960,14 +898,14 @@ function! s:PollSignatureHelp( ... ) - return - endif - -- if !s:Pyeval( 'ycm_state.SignatureHelpRequestReady()' ) -+ if !py3eval( 'ycm_state.SignatureHelpRequestReady()' ) - let s:pollers.signature_help.id = timer_start( - \ s:pollers.signature_help.wait_milliseconds, - \ function( 's:PollSignatureHelp' ) ) - return - endif - -- let s:signature_help = s:Pyeval( 'ycm_state.GetSignatureHelpResponse()' ) -+ let s:signature_help = py3eval( 'ycm_state.GetSignatureHelpResponse()' ) - call s:UpdateSignatureHelp() - endfunction - -@@ -1023,7 +961,7 @@ function! s:UpdateSignatureHelp() - return - endif - -- call s:Pyeval( -+ call py3eval( - \ 'ycm_state.UpdateSignatureHelp( vim.eval( "s:signature_help" ) )' ) - endfunction - -@@ -1035,12 +973,12 @@ function! s:ClearSignatureHelp() - - call s:StopPoller( s:pollers.signature_help ) - let s:signature_help = s:default_signature_help -- call s:Pyeval( 'ycm_state.ClearSignatureHelp()' ) -+ call py3eval( 'ycm_state.ClearSignatureHelp()' ) - endfunction - - - function! youcompleteme#ServerPid() -- return s:Pyeval( 'ycm_state.ServerPid()' ) -+ return py3eval( 'ycm_state.ServerPid()' ) - endfunction - - -@@ -1049,7 +987,7 @@ function! s:SetUpCommands() - command! YcmDebugInfo call s:DebugInfo() - command! -nargs=* -complete=custom,youcompleteme#LogsComplete - \ YcmToggleLogs call s:ToggleLogs() -- if s:Pyeval( 'vimsupport.VimVersionAtLeast( "7.4.1898" )' ) -+ if py3eval( 'vimsupport.VimVersionAtLeast( "7.4.1898" )' ) - command! -nargs=* -complete=custom,youcompleteme#SubCommandsComplete -range - \ YcmCompleter call s:CompleterCommand(, - \ , -@@ -1073,7 +1011,7 @@ endfunction - function! s:RestartServer() - call s:SetUpOptions() - -- exec s:python_command "ycm_state.RestartServer()" -+ py3 ycm_state.RestartServer() - - call s:StopPoller( s:pollers.receive_messages ) - call s:ClearSignatureHelp() -@@ -1087,7 +1025,7 @@ endfunction - - function! s:DebugInfo() - echom "Printing YouCompleteMe debug information..." -- let debug_info = s:Pyeval( 'ycm_state.DebugInfo()' ) -+ let debug_info = py3eval( 'ycm_state.DebugInfo()' ) - for line in split( debug_info, "\n" ) - echom '-- ' . line - endfor -@@ -1095,50 +1033,50 @@ endfunction - - - function! s:ToggleLogs(...) -- exec s:python_command "ycm_state.ToggleLogs( *vim.eval( 'a:000' ) )" -+ py3 ycm_state.ToggleLogs( *vim.eval( 'a:000' ) ) - endfunction - - - function! youcompleteme#LogsComplete( arglead, cmdline, cursorpos ) -- return join( s:Pyeval( 'list( ycm_state.GetLogfiles() )' ), "\n" ) -+ return join( py3eval( 'list( ycm_state.GetLogfiles() )' ), "\n" ) - endfunction - - - function! s:CompleterCommand( mods, count, line1, line2, ... ) -- exec s:python_command "ycm_state.SendCommandRequest(" . -- \ "vim.eval( 'a:000' )," . -- \ "vim.eval( 'a:mods' )," . -- \ "vimsupport.GetBoolValue( 'a:count != -1' )," . -- \ "vimsupport.GetIntValue( 'a:line1' )," . -- \ "vimsupport.GetIntValue( 'a:line2' ) )" -+ py3 ycm_state.SendCommandRequest( -+ \ vim.eval( 'a:000' ), -+ \ vim.eval( 'a:mods' ), -+ \ vimsupport.GetBoolValue( 'a:count != -1' ), -+ \ vimsupport.GetIntValue( 'a:line1' ), -+ \ vimsupport.GetIntValue( 'a:line2' ) ) - endfunction - - - function! youcompleteme#SubCommandsComplete( arglead, cmdline, cursorpos ) -- return join( s:Pyeval( 'ycm_state.GetDefinedSubcommands()' ), "\n" ) -+ return join( py3eval( 'ycm_state.GetDefinedSubcommands()' ), "\n" ) - endfunction - - - function! youcompleteme#OpenGoToList() -- exec s:python_command "vimsupport.PostVimMessage(" . -+ py3 vimsupport.PostVimMessage( - \ "'WARNING: youcompleteme#OpenGoToList function is deprecated. " . -- \ "Do NOT use it.' )" -- exec s:python_command "vimsupport.OpenQuickFixList( True, True )" -+ \ "Do NOT use it.'" ) -+ py3 vimsupport.OpenQuickFixList( True, True ) - endfunction - - - function! s:ShowDiagnostics() -- exec s:python_command "ycm_state.ShowDiagnostics()" -+ py3 ycm_state.ShowDiagnostics() - endfunction - - - function! s:ShowDetailedDiagnostic() -- exec s:python_command "ycm_state.ShowDetailedDiagnostic()" -+ py3 ycm_state.ShowDetailedDiagnostic() - endfunction - - - function! s:ForceCompileAndDiagnostics() -- exec s:python_command "ycm_state.ForceCompileAndDiagnostics()" -+ py3 ycm_state.ForceCompileAndDiagnostics() - endfunction - - -diff --git a/azure-pipelines.yml b/azure-pipelines.yml -index c23f2a62d..3b43a69c4 100644 ---- a/azure-pipelines.yml -+++ b/azure-pipelines.yml -@@ -18,10 +18,6 @@ jobs: - vmImage: 'ubuntu-16.04' - strategy: - matrix: -- 'Python 2.7': -- # Tests are failing on Python 2.7.0 with the exception -- # "TypeError: argument can't be " -- YCM_PYTHON_VERSION: '2.7.13' - 'Python 3.5': - YCM_PYTHON_VERSION: '3.5.3' - maxParallel: 2 -@@ -49,9 +45,6 @@ jobs: - vmImage: 'ubuntu-16.04' - strategy: - matrix: -- 'Python 2.7': -- IMAGE: ycm-vim-py2 -- PIP: pip - 'Python 3.5': - IMAGE: ycm-vim-py3 - PIP: pip3 -@@ -82,8 +75,6 @@ jobs: - vmImage: 'macOS-10.13' - strategy: - matrix: -- 'Python 2.7': -- YCM_PYTHON_VERSION: '2.7.13' - 'Python 3.5': - YCM_PYTHON_VERSION: '3.5.3' - maxParallel: 2 -@@ -109,10 +100,6 @@ jobs: - vmImage: 'windows-2019' - strategy: - matrix: -- # We only test Python 2.7 on 64-bit. -- 'Python 2.7 64-bit': -- YCM_PYTHON_VERSION: '2.7' -- YCM_ARCH: x64 - 'Python 3.7 32-bit': - YCM_PYTHON_VERSION: '3.7' - YCM_ARCH: x86 -diff --git a/install.sh b/install.sh -index 8c9c2fd1b..82ecf88c1 100755 ---- a/install.sh -+++ b/install.sh -@@ -5,13 +5,4 @@ echo "WARNING: this script is deprecated. Use the install.py script instead." 1> - - SCRIPT_DIR=$(dirname $0 || exit $?) - --command_exists() { -- command -v "$1" >/dev/null 2>&1 ; --} -- --PYTHON_BINARY=python --if command_exists python2; then -- PYTHON_BINARY=python2 --fi -- --$PYTHON_BINARY "$SCRIPT_DIR/install.py" "$@" || exit $? -+python3 "$SCRIPT_DIR/install.py" "$@" || exit $? -diff --git a/plugin/youcompleteme.vim b/plugin/youcompleteme.vim -index d2994c25a..bfe77516a 100644 ---- a/plugin/youcompleteme.vim -+++ b/plugin/youcompleteme.vim -@@ -55,17 +55,17 @@ elseif !has( 'timers' ) - call s:restore_cpo() - finish - elseif ( v:version > 800 || ( v:version == 800 && has( 'patch1436' ) ) ) && -- \ !has( 'python_compiled' ) && !has( 'python3_compiled' ) -+ \ !has( 'python3_compiled' ) - echohl WarningMsg | - \ echomsg "YouCompleteMe unavailable: requires Vim compiled with " . -- \ "Python (2.7.1+ or 3.5.1+) support." | -+ \ "Python (3.5.1+) support." | - \ echohl None - call s:restore_cpo() - finish --" These calls try to load the Python 2 and Python 3 libraries when Vim is -+" These calls try to load the Python 3 libraries when Vim is - " compiled dynamically against them. Since only one can be loaded at a time on - " some platforms, we first check if Python 3 is available. --elseif !has( 'python3' ) && !has( 'python' ) -+elseif !has( 'python3' ) - echohl WarningMsg | - \ echomsg "YouCompleteMe unavailable: unable to load Python." | - \ echohl None -diff --git a/python/ycm/base.py b/python/ycm/base.py -index 7013dfed1..2d331c618 100644 ---- a/python/ycm/base.py -+++ b/python/ycm/base.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm import vimsupport - from ycmd import identifier_utils - -diff --git a/python/ycm/buffer.py b/python/ycm/buffer.py -index b95c0da32..848adc898 100644 ---- a/python/ycm/buffer.py -+++ b/python/ycm/buffer.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm import vimsupport - from ycm.client.event_notification import EventNotification - from ycm.diagnostic_interface import DiagnosticInterface -@@ -34,7 +27,7 @@ - # Used to store buffer related information like diagnostics, latest parse - # request. Stores buffer change tick at the parse request moment, allowing - # to effectively determine whether reparse is needed for the buffer. --class Buffer( object ): -+class Buffer: - - def __init__( self, bufnr, user_options, filetypes ): - self._number = bufnr -diff --git a/python/ycm/client/base_request.py b/python/ycm/client/base_request.py -index ec7d5ecea..e474fc54f 100644 ---- a/python/ycm/client/base_request.py -+++ b/python/ycm/client/base_request.py -@@ -15,21 +15,15 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - import logging - import json - import vim --from future.utils import native - from base64 import b64decode, b64encode -+from hmac import compare_digest -+from urllib.parse import urljoin, urlparse - from ycm import vimsupport --from ycmd.utils import ToBytes, urljoin, urlparse, GetCurrentDirectory --from ycmd.hmac_utils import CreateRequestHmac, CreateHmac, SecureBytesEqual -+from ycmd.utils import ToBytes, GetCurrentDirectory -+from ycmd.hmac_utils import CreateRequestHmac, CreateHmac - from ycmd.responses import ServerError, UnknownExtraConf - - _HEADERS = { 'content-type': 'application/json' } -@@ -40,7 +34,7 @@ - _logger = logging.getLogger( __name__ ) - - --class BaseRequest( object ): -+class BaseRequest: - - def __init__( self ): - self._should_resend = False -@@ -298,13 +292,13 @@ def _ToUtf8Json( data ): - def _ValidateResponseObject( response ): - our_hmac = CreateHmac( response.content, BaseRequest.hmac_secret ) - their_hmac = ToBytes( b64decode( response.headers[ _HMAC_HEADER ] ) ) -- if not SecureBytesEqual( our_hmac, their_hmac ): -+ if not compare_digest( our_hmac, their_hmac ): - raise RuntimeError( 'Received invalid HMAC for response!' ) - return True - - - def _BuildUri( handler ): -- return native( ToBytes( urljoin( BaseRequest.server_location, handler ) ) ) -+ return ToBytes( urljoin( BaseRequest.server_location, handler ) ) - - - def MakeServerException( data ): -diff --git a/python/ycm/client/command_request.py b/python/ycm/client/command_request.py -index 168af18dd..ac25304e9 100644 ---- a/python/ycm/client/command_request.py -+++ b/python/ycm/client/command_request.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.client.base_request import BaseRequest, BuildRequestData - from ycm import vimsupport - from ycmd.utils import ToUnicode -diff --git a/python/ycm/client/completer_available_request.py b/python/ycm/client/completer_available_request.py -index 9ee9dd3f8..7822876fc 100644 ---- a/python/ycm/client/completer_available_request.py -+++ b/python/ycm/client/completer_available_request.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.client.base_request import BaseRequest, BuildRequestData - - -diff --git a/python/ycm/client/completion_request.py b/python/ycm/client/completion_request.py -index fa7cd223a..8e0b72771 100644 ---- a/python/ycm/client/completion_request.py -+++ b/python/ycm/client/completion_request.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - import logging - from ycmd.utils import ToUnicode - from ycm.client.base_request import ( BaseRequest, DisplayServerException, -diff --git a/python/ycm/client/debug_info_request.py b/python/ycm/client/debug_info_request.py -index 32d7bd3df..95949086b 100644 ---- a/python/ycm/client/debug_info_request.py -+++ b/python/ycm/client/debug_info_request.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.client.base_request import BaseRequest, BuildRequestData - - -diff --git a/python/ycm/client/event_notification.py b/python/ycm/client/event_notification.py -index bdbe07e34..eee90eefe 100644 ---- a/python/ycm/client/event_notification.py -+++ b/python/ycm/client/event_notification.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.client.base_request import BaseRequest, BuildRequestData - - -diff --git a/python/ycm/client/messages_request.py b/python/ycm/client/messages_request.py -index 0f1bd2aab..d382d1445 100644 ---- a/python/ycm/client/messages_request.py -+++ b/python/ycm/client/messages_request.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.client.base_request import BaseRequest, BuildRequestData - from ycm.vimsupport import PostVimMessage - -diff --git a/python/ycm/client/omni_completion_request.py b/python/ycm/client/omni_completion_request.py -index 397ba2128..3733603b1 100644 ---- a/python/ycm/client/omni_completion_request.py -+++ b/python/ycm/client/omni_completion_request.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.client.completion_request import CompletionRequest - - -diff --git a/python/ycm/client/shutdown_request.py b/python/ycm/client/shutdown_request.py -index ae42734fb..159814315 100644 ---- a/python/ycm/client/shutdown_request.py -+++ b/python/ycm/client/shutdown_request.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.client.base_request import BaseRequest - - TIMEOUT_SECONDS = 0.1 -diff --git a/python/ycm/client/signature_help_request.py b/python/ycm/client/signature_help_request.py -index 292b3407c..f65c47d39 100644 ---- a/python/ycm/client/signature_help_request.py -+++ b/python/ycm/client/signature_help_request.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - import logging - from ycm.client.base_request import ( BaseRequest, DisplayServerException, - MakeServerException ) -diff --git a/python/ycm/client/ycmd_keepalive.py b/python/ycm/client/ycmd_keepalive.py -index 278ef86ea..a13727f73 100644 ---- a/python/ycm/client/ycmd_keepalive.py -+++ b/python/ycm/client/ycmd_keepalive.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - import time - from threading import Thread - from ycm.client.base_request import BaseRequest -@@ -30,7 +23,7 @@ - # This class can be used to keep the ycmd server alive for the duration of the - # life of the client. By default, ycmd shuts down if it doesn't see a request in - # a while. --class YcmdKeepalive( object ): -+class YcmdKeepalive: - def __init__( self, ping_interval_seconds = 60 * 10 ): - self._keepalive_thread = Thread( target = self._ThreadMain ) - self._keepalive_thread.daemon = True -diff --git a/python/ycm/diagnostic_filter.py b/python/ycm/diagnostic_filter.py -index 7448f2c0a..eb651df48 100644 ---- a/python/ycm/diagnostic_filter.py -+++ b/python/ycm/diagnostic_filter.py -@@ -15,19 +15,11 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- --from future.utils import iterkeys, iteritems - from ycm import vimsupport - import re - - --class DiagnosticFilter( object ): -+class DiagnosticFilter: - def __init__( self, config_or_filters ): - if isinstance( config_or_filters, list ): - self._filters = config_or_filters -@@ -55,7 +47,7 @@ def SubsetForTypes( self, filetypes ): - def CreateFromOptions( user_options ): - all_filters = user_options[ 'filter_diagnostics' ] - compiled_by_type = {} -- for type_spec, filter_value in iteritems( all_filters ): -+ for type_spec, filter_value in all_filters.items(): - filetypes = [ type_spec ] - if type_spec.find( ',' ) != -1: - filetypes = type_spec.split( ',' ) -@@ -65,7 +57,7 @@ def CreateFromOptions( user_options ): - return _MasterDiagnosticFilter( compiled_by_type ) - - --class _MasterDiagnosticFilter( object ): -+class _MasterDiagnosticFilter: - - def __init__( self, all_filters ): - self._all_filters = all_filters -@@ -139,7 +131,7 @@ def _CompileFilters( config ): - """Given a filter config dictionary, return a list of compiled filters""" - filters = [] - -- for filter_type in iterkeys( config ): -+ for filter_type in config.keys(): - compiler = FILTER_COMPILERS.get( filter_type ) - - if compiler is not None: -diff --git a/python/ycm/diagnostic_interface.py b/python/ycm/diagnostic_interface.py -index 5475d961a..3e4d8f99b 100644 ---- a/python/ycm/diagnostic_interface.py -+++ b/python/ycm/diagnostic_interface.py -@@ -15,20 +15,12 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- --from future.utils import itervalues, iteritems - from collections import defaultdict - from ycm import vimsupport - from ycm.diagnostic_filter import DiagnosticFilter, CompileLevel - - --class DiagnosticInterface( object ): -+class DiagnosticInterface: - def __init__( self, bufnr, user_options ): - self._bufnr = bufnr - self._user_options = user_options -@@ -114,7 +106,7 @@ def _EchoDiagnosticForLine( self, line_num ): - - def _DiagnosticsCount( self, predicate ): - count = 0 -- for diags in itervalues( self._line_to_diags ): -+ for diags in self._line_to_diags.values(): - count += sum( 1 for d in diags if predicate( d ) ) - return count - -@@ -136,7 +128,7 @@ def UpdateMatches( self ): - - matches_to_remove = vimsupport.GetDiagnosticMatchesInCurrentWindow() - -- for diags in itervalues( self._line_to_diags ): -+ for diags in self._line_to_diags.values(): - # Insert squiggles in reverse order so that errors overlap warnings. - for diag in reversed( diags ): - group = ( 'YcmErrorSection' if _DiagnosticIsError( diag ) else -@@ -157,7 +149,7 @@ def UpdateMatches( self ): - def _UpdateSigns( self ): - signs_to_unplace = vimsupport.GetSignsInBuffer( self._bufnr ) - -- for line, diags in iteritems( self._line_to_diags ): -+ for line, diags in self._line_to_diags.items(): - if not diags: - continue - -@@ -185,7 +177,7 @@ def _ConvertDiagListToDict( self ): - line_number = location[ 'line_num' ] - self._line_to_diags[ line_number ].append( diag ) - -- for diags in itervalues( self._line_to_diags ): -+ for diags in self._line_to_diags.values(): - # We also want errors to be listed before warnings so that errors aren't - # hidden by the warnings; Vim won't place a sign over an existing one. - diags.sort( key = lambda diag: ( diag[ 'kind' ], -diff --git a/python/ycm/omni_completer.py b/python/ycm/omni_completer.py -index a62a968b3..8c9f6a0fc 100644 ---- a/python/ycm/omni_completer.py -+++ b/python/ycm/omni_completer.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - import vim - from ycm import vimsupport - from ycmd import utils -diff --git a/python/ycm/paths.py b/python/ycm/paths.py -index 013a66e30..055c9d90a 100644 ---- a/python/ycm/paths.py -+++ b/python/ycm/paths.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - import os - import sys - import vim -@@ -33,7 +26,7 @@ - 'ycmd' ) - WIN_PYTHON_PATH = os.path.join( sys.exec_prefix, 'python.exe' ) - PYTHON_BINARY_REGEX = re.compile( -- r'python((2(\.7)?)|(3(\.[5-9])?))?(.exe)?$', re.IGNORECASE ) -+ r'python(3(\.[5-9])?)?(.exe)?$', re.IGNORECASE ) - - - # Not caching the result of this function; users shouldn't have to restart Vim -@@ -51,7 +44,7 @@ def PathToPythonInterpreter(): - return python_interpreter - - raise RuntimeError( "Path in 'g:ycm_server_python_interpreter' option " -- "does not point to a valid Python 2.7 or 3.5+." ) -+ "does not point to a valid Python 3.5+." ) - - python_interpreter = _PathToPythonUsedDuringBuild() - if python_interpreter and utils.GetExecutable( python_interpreter ): -@@ -66,18 +59,12 @@ def PathToPythonInterpreter(): - if _EndsWithPython( python_interpreter ): - return python_interpreter - -- # As a last resort, we search python in the PATH. We prefer Python 2 over 3 -- # for the sake of backwards compatibility with ycm_extra_conf.py files out -- # there; few people wrote theirs to work on py3. -- # So we check 'python2' before 'python' because on some distributions (Arch -- # Linux for example), python refers to python3. -- python_interpreter = utils.PathToFirstExistingExecutable( [ 'python2', -- 'python', -- 'python3' ] ) -+ python_interpreter = utils.PathToFirstExistingExecutable( [ 'python3', -+ 'python' ] ) - if python_interpreter: - return python_interpreter - -- raise RuntimeError( "Cannot find Python 2.7 or 3.5+. " -+ raise RuntimeError( "Cannot find Python 3.5+. " - "Set the 'g:ycm_server_python_interpreter' option " - "to a Python interpreter path." ) - -@@ -88,13 +75,12 @@ def _PathToPythonUsedDuringBuild(): - try: - filepath = os.path.join( DIR_OF_YCMD, 'PYTHON_USED_DURING_BUILDING' ) - return utils.ReadFile( filepath ).strip() -- # We need to check for IOError for Python2 and OSError for Python3 -- except ( IOError, OSError ): -+ except OSError: - return None - - - def _EndsWithPython( path ): -- """Check if given path ends with a python 2.7 or 3.5+ name.""" -+ """Check if given path ends with a python 3.5+ name.""" - return path and PYTHON_BINARY_REGEX.search( path ) is not None - - -diff --git a/python/ycm/signature_help.py b/python/ycm/signature_help.py -index 821aa4350..0fd6dd3a7 100644 ---- a/python/ycm/signature_help.py -+++ b/python/ycm/signature_help.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - import vim - import json - from ycm import vimsupport -@@ -29,7 +22,7 @@ - from ycm.vimsupport import memoize, GetIntValue - - --class SignatureHelpState( object ): -+class SignatureHelpState: - ACTIVE = 'ACTIVE' - INACTIVE = 'INACTIVE' - -diff --git a/python/ycm/syntax_parse.py b/python/ycm/syntax_parse.py -index 0fbdad9d0..aa44eb5e0 100644 ---- a/python/ycm/syntax_parse.py -+++ b/python/ycm/syntax_parse.py -@@ -15,14 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- --from future.utils import itervalues - import re - from ycm import vimsupport - -@@ -61,7 +53,7 @@ - } - - --class SyntaxGroup( object ): -+class SyntaxGroup: - def __init__( self, name, lines = None ): - self.name = name - self.lines = lines if lines else [] -@@ -169,7 +161,7 @@ def GetParentNames( group ): - parent_names.append( line[ len( links_to ): ] ) - return parent_names - -- for group in itervalues( group_name_to_group ): -+ for group in group_name_to_group.values(): - parent_names = GetParentNames( group ) - - for parent_name in parent_names: -diff --git a/python/ycm/tests/__init__.py b/python/ycm/tests/__init__.py -index 5ee0f8c8a..ad542f791 100644 ---- a/python/ycm/tests/__init__.py -+++ b/python/ycm/tests/__init__.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.tests.test_utils import MockVimModule - MockVimModule() - -diff --git a/python/ycm/tests/base_test.py b/python/ycm/tests/base_test.py -index 15e51b2ce..53473165c 100644 ---- a/python/ycm/tests/base_test.py -+++ b/python/ycm/tests/base_test.py -@@ -1,7 +1,5 @@ --# coding: utf-8 --# - # Copyright (C) 2013 Google Inc. --# 2016 YouCompleteMe contributors -+# 2020 YouCompleteMe contributors - # - # This file is part of YouCompleteMe. - # -@@ -18,13 +16,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - import contextlib - from nose.tools import eq_, ok_ - from mock import patch -diff --git a/python/ycm/tests/client/base_request_test.py b/python/ycm/tests/client/base_request_test.py -index 997313a0c..29ddc8bf0 100644 ---- a/python/ycm/tests/client/base_request_test.py -+++ b/python/ycm/tests/client/base_request_test.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.tests.test_utils import MockVimBuffers, MockVimModule, VimBuffer - MockVimModule() - -diff --git a/python/ycm/tests/client/command_request_test.py b/python/ycm/tests/client/command_request_test.py -index ac5f83ee6..fc4b3f4ce 100644 ---- a/python/ycm/tests/client/command_request_test.py -+++ b/python/ycm/tests/client/command_request_test.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.tests.test_utils import ExtendedMock, MockVimModule - MockVimModule() - -@@ -31,7 +24,7 @@ - from ycm.client.command_request import CommandRequest - - --class GoToResponse_QuickFix_test( object ): -+class GoToResponse_QuickFix_test: - """This class tests the generation of QuickFix lists for GoTo responses which - return multiple locations, such as the Python completer and JavaScript - completer. It mostly proves that we use 1-based indexing for the column -@@ -118,7 +111,7 @@ def _CheckGoToList( self, - set_fitting_height.assert_called_once_with() - - --class Response_Detection_test( object ): -+class Response_Detection_test: - - def BasicResponse_test( self ): - def _BasicResponseTest( command, response ): -diff --git a/python/ycm/tests/client/completion_request_test.py b/python/ycm/tests/client/completion_request_test.py -index a39e4499f..ef7cdd3c2 100644 ---- a/python/ycm/tests/client/completion_request_test.py -+++ b/python/ycm/tests/client/completion_request_test.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from nose.tools import eq_ - from ycm.tests.test_utils import MockVimModule - vim_mock = MockVimModule() -@@ -29,7 +22,7 @@ - from ycm.client import completion_request - - --class ConvertCompletionResponseToVimDatas_test( object ): -+class ConvertCompletionResponseToVimDatas_test: - """ This class tests the - completion_request._ConvertCompletionResponseToVimDatas method """ - -diff --git a/python/ycm/tests/client/debug_info_request_test.py b/python/ycm/tests/client/debug_info_request_test.py -index 9ce2a4331..93f7ac393 100644 ---- a/python/ycm/tests/client/debug_info_request_test.py -+++ b/python/ycm/tests/client/debug_info_request_test.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from copy import deepcopy - from hamcrest import assert_that, contains_string, equal_to - -diff --git a/python/ycm/tests/client/messages_request_test.py b/python/ycm/tests/client/messages_request_test.py -index 1f89f7170..2504ca074 100644 ---- a/python/ycm/tests/client/messages_request_test.py -+++ b/python/ycm/tests/client/messages_request_test.py -@@ -15,14 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - -- --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.tests.test_utils import MockVimModule - MockVimModule() - -diff --git a/python/ycm/tests/client/omni_completion_request_tests.py b/python/ycm/tests/client/omni_completion_request_tests.py -index 39c267b4b..0028ee3f7 100644 ---- a/python/ycm/tests/client/omni_completion_request_tests.py -+++ b/python/ycm/tests/client/omni_completion_request_tests.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from mock import MagicMock - from nose.tools import eq_ - -diff --git a/python/ycm/tests/command_test.py b/python/ycm/tests/command_test.py -index 0652207b8..f4e909db1 100644 ---- a/python/ycm/tests/command_test.py -+++ b/python/ycm/tests/command_test.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.tests.test_utils import MockVimModule, MockVimBuffers, VimBuffer - MockVimModule() - -diff --git a/python/ycm/tests/completion_test.py b/python/ycm/tests/completion_test.py -index 00ac7cf38..db9c972da 100644 ---- a/python/ycm/tests/completion_test.py -+++ b/python/ycm/tests/completion_test.py -@@ -1,5 +1,3 @@ --# coding: utf-8 --# - # Copyright (C) 2016 YouCompleteMe contributors - # - # This file is part of YouCompleteMe. -@@ -17,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.tests.test_utils import ( CurrentWorkingDirectory, ExtendedMock, - MockVimModule, MockVimBuffers, VimBuffer ) - MockVimModule() -diff --git a/python/ycm/tests/diagnostic_filter_test.py b/python/ycm/tests/diagnostic_filter_test.py -index e4a74b227..3591feb93 100644 ---- a/python/ycm/tests/diagnostic_filter_test.py -+++ b/python/ycm/tests/diagnostic_filter_test.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.tests.test_utils import MockVimModule - MockVimModule() - -diff --git a/python/ycm/tests/event_notification_test.py b/python/ycm/tests/event_notification_test.py -index ce1450ae0..85e73dcb4 100644 ---- a/python/ycm/tests/event_notification_test.py -+++ b/python/ycm/tests/event_notification_test.py -@@ -1,5 +1,3 @@ --# coding: utf-8 --# - # Copyright (C) 2015-2018 YouCompleteMe contributors - # - # This file is part of YouCompleteMe. -@@ -17,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.tests.test_utils import ( CurrentWorkingDirectory, ExtendedMock, - MockVimBuffers, MockVimModule, VimBuffer, - VimSign ) -diff --git a/python/ycm/tests/mock_utils.py b/python/ycm/tests/mock_utils.py -index 3770202de..36faa10a0 100644 ---- a/python/ycm/tests/mock_utils.py -+++ b/python/ycm/tests/mock_utils.py -@@ -14,18 +14,11 @@ - # - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - import mock - import requests - - --class FakeResponse( object ): -+class FakeResponse: - """A fake version of a requests response object, just about suitable for - mocking a server response. Not usually used directly. See - MockServerResponse* methods""" -@@ -46,7 +39,7 @@ def raise_for_status( self ): - raise self._exception - - --class FakeFuture( object ): -+class FakeFuture: - """A fake version of a future response object, just about suitable for - mocking a server response as generated by PostDataToHandlerAsync. - Not usually used directly. See MockAsyncServerResponse* methods""" -diff --git a/python/ycm/tests/paths_test.py b/python/ycm/tests/paths_test.py -index 1bd4390ed..86c7c8069 100644 ---- a/python/ycm/tests/paths_test.py -+++ b/python/ycm/tests/paths_test.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.tests.test_utils import MockVimModule - MockVimModule() - -@@ -39,20 +32,6 @@ def EndsWithPython_Bad( path ): - 'Path {0} does end with a Python name.'.format( path ) ) - - --def EndsWithPython_Python2Paths_test(): -- python_paths = [ -- 'python', -- 'python2', -- '/usr/bin/python2.7', -- '/home/user/.pyenv/shims/python2.7', -- r'C:\Python27\python.exe', -- '/Contents/MacOS/Python' -- ] -- -- for path in python_paths: -- yield EndsWithPython_Good, path -- -- - def EndsWithPython_Python3Paths_test(): - python_paths = [ - 'python3', -@@ -71,7 +50,7 @@ def EndsWithPython_BadPaths_test(): - '', - '/opt/local/bin/vim', - r'C:\Program Files\Vim\vim74\gvim.exe', -- '/usr/bin/python2.5', -+ '/usr/bin/python2.7', - '/home/user/.pyenv/shims/python3.2', - ] - -diff --git a/python/ycm/tests/postcomplete_test.py b/python/ycm/tests/postcomplete_test.py -index e1ee26230..bccf95739 100644 ---- a/python/ycm/tests/postcomplete_test.py -+++ b/python/ycm/tests/postcomplete_test.py -@@ -17,13 +17,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.tests.test_utils import MockVimModule - MockVimModule() - -diff --git a/python/ycm/tests/signature_help_test.py b/python/ycm/tests/signature_help_test.py -index d46c5fc16..f993376ab 100644 ---- a/python/ycm/tests/signature_help_test.py -+++ b/python/ycm/tests/signature_help_test.py -@@ -1,5 +1,3 @@ --# coding: utf-8 --# - # Copyright (C) 2019 YouCompleteMe contributors - # - # This file is part of YouCompleteMe. -@@ -17,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --# Intentionally not importing unicode_literals! --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from hamcrest import ( assert_that, - empty ) - from ycm import signature_help as sh -diff --git a/python/ycm/tests/syntax_parse_test.py b/python/ycm/tests/syntax_parse_test.py -index 7c6566339..a807cd7ad 100644 ---- a/python/ycm/tests/syntax_parse_test.py -+++ b/python/ycm/tests/syntax_parse_test.py -@@ -16,13 +16,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.tests.test_utils import MockVimModule - MockVimModule() - -diff --git a/python/ycm/tests/test_utils.py b/python/ycm/tests/test_utils.py -index 1f076d05d..fc4349fe2 100644 ---- a/python/ycm/tests/test_utils.py -+++ b/python/ycm/tests/test_utils.py -@@ -15,15 +15,7 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from collections import defaultdict, namedtuple --from future.utils import iteritems, PY2 - from mock import DEFAULT, MagicMock, patch - from hamcrest import assert_that, equal_to - import contextlib -@@ -39,7 +31,7 @@ - except ImportError: - from unittest2 import skipIf - --from ycmd.utils import GetCurrentDirectory, OnMac, OnWindows, ToBytes, ToUnicode -+from ycmd.utils import GetCurrentDirectory, OnMac, OnWindows, ToUnicode - - - BUFNR_REGEX = re.compile( '^bufnr\\(\'(?P.+)\', ([01])\\)$' ) -@@ -180,8 +172,7 @@ def _MockVimBufferEval( value ): - if match: - findstart = int( match.group( 'findstart' ) ) - base = match.group( 'base' ) -- value = current_buffer.omnifunc( findstart, base ) -- return value if findstart else ToBytesOnPY2( value ) -+ return current_buffer.omnifunc( findstart, base ) - - return None - -@@ -201,7 +192,7 @@ def _MockVimOptionsEval( value ): - - if value == 'keys( g: )': - global_options = {} -- for key, value in iteritems( VIM_OPTIONS ): -+ for key, value in VIM_OPTIONS.items(): - if key.startswith( 'g:' ): - global_options[ key[ 2: ] ] = value - return global_options -@@ -382,7 +373,7 @@ def _MockVimCommand( command ): - return DEFAULT - - --class VimBuffer( object ): -+class VimBuffer: - """An object that looks like a vim.buffer object: - - |name| : full path of the buffer with symbolic links resolved; - - |number| : buffer number; -@@ -457,7 +448,7 @@ def __repr__( self ): - self.number ) - - --class VimBuffers( object ): -+class VimBuffers: - """An object that looks like a vim.buffers object.""" - - def __init__( self, buffers ): -@@ -482,7 +473,7 @@ def pop( self, index ): - return self._buffers.pop( index ) - - --class VimWindow( object ): -+class VimWindow: - """An object that looks like a vim.window object: - - |number|: number of the window; - - |buffer_object|: a VimBuffer object representing the buffer inside the -@@ -503,7 +494,7 @@ def __repr__( self ): - self.cursor ) - - --class VimWindows( object ): -+class VimWindows: - """An object that looks like a vim.windows object.""" - - def __init__( self, buffers, cursor ): -@@ -530,7 +521,7 @@ def __iter__( self ): - return iter( self._windows ) - - --class VimCurrent( object ): -+class VimCurrent: - """An object that looks like a vim.current object. |current_window| must be a - VimWindow object.""" - -@@ -540,7 +531,7 @@ def __init__( self, current_window ): - self.line = self.buffer.contents[ current_window.cursor[ 0 ] - 1 ] - - --class VimMatch( object ): -+class VimMatch: - - def __init__( self, group, pattern ): - current_window = VIM_MOCK.current.window.number -@@ -565,7 +556,7 @@ def __getitem__( self, key ): - return self.id - - --class VimSign( object ): -+class VimSign: - - def __init__( self, sign_id, line, name, bufnr ): - self.id = sign_id -@@ -717,22 +708,3 @@ def Wrapper( *args, **kwargs ): - return Wrapper - - return decorator -- -- --def ToBytesOnPY2( data ): -- # To test the omnifunc, etc. returning strings, which can be of different -- # types depending on python version, we use ToBytes on PY2 and just the native -- # str on python3. This roughly matches what happens between py2 and py3 -- # versions within Vim. -- if not PY2: -- return data -- -- if isinstance( data, int ): -- return data -- if isinstance( data, list ): -- return [ ToBytesOnPY2( item ) for item in data ] -- if isinstance( data, dict ): -- for item in data: -- data[ item ] = ToBytesOnPY2( data[ item ] ) -- return data -- return ToBytes( data ) -diff --git a/python/ycm/tests/vimsupport_test.py b/python/ycm/tests/vimsupport_test.py -index ea9e006c5..bb79aef26 100644 ---- a/python/ycm/tests/vimsupport_test.py -+++ b/python/ycm/tests/vimsupport_test.py -@@ -1,5 +1,3 @@ --# coding: utf-8 --# - # Copyright (C) 2015-2018 YouCompleteMe contributors - # - # This file is part of YouCompleteMe. -@@ -16,14 +14,6 @@ - # - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . -- --# Intentionally not importing unicode_literals! --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.tests import PathToTestFile - from ycm.tests.test_utils import ( CurrentWorkingDirectory, ExtendedMock, - MockVimBuffers, MockVimModule, Version, -@@ -1705,8 +1695,6 @@ def InsertNamespace_append_test( vim_current, *args ): - - @patch( 'vim.command', new_callable = ExtendedMock ) - def JumpToLocation_SameFile_SameBuffer_NoSwapFile_test( vim_command ): -- # No 'u' prefix for the current buffer name string to simulate Vim returning -- # bytes on Python 2 but unicode on Python 3. - current_buffer = VimBuffer( 'uni¢𐍈d€' ) - with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim: - vimsupport.JumpToLocation( os.path.realpath( u'uni¢𐍈d€' ), -diff --git a/python/ycm/tests/youcompleteme_test.py b/python/ycm/tests/youcompleteme_test.py -index 069d4f30f..42a436093 100644 ---- a/python/ycm/tests/youcompleteme_test.py -+++ b/python/ycm/tests/youcompleteme_test.py -@@ -15,13 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- - from ycm.client.messages_request import MessagesPoll - from ycm.tests.test_utils import ( ExtendedMock, - MockVimBuffers, -@@ -71,7 +64,7 @@ def YouCompleteMe_InvalidPythonInterpreterPath_test( post_vim_message ): - post_vim_message.assert_called_once_with( - "Unable to start the ycmd server. " - "Path in 'g:ycm_server_python_interpreter' option does not point " -- "to a valid Python 2.7 or 3.5+. " -+ "to a valid Python 3.5+. " - "Correct the error then restart the server with ':YcmRestartServer'." ) - - post_vim_message.reset_mock() -@@ -98,7 +91,7 @@ def YouCompleteMe_NoPythonInterpreterFound_test( post_vim_message, *args ): - - assert_that( ycm.IsServerAlive(), equal_to( False ) ) - post_vim_message.assert_called_once_with( -- "Unable to start the ycmd server. Cannot find Python 2.7 or 3.5+. " -+ "Unable to start the ycmd server. Cannot find Python 3.5+. " - "Set the 'g:ycm_server_python_interpreter' option to a Python " - "interpreter path. " - "Correct the error then restart the server with ':YcmRestartServer'." ) -@@ -154,28 +147,6 @@ def YouCompleteMe_NotifyUserIfServerCrashed_MissingCore_test(): - } ) - - --def YouCompleteMe_NotifyUserIfServerCrashed_Python2Core_test(): -- message = ( "The ycmd server SHUT DOWN (restart with ':YcmRestartServer'). " -- "YCM core library compiled for Python 2 but loaded in Python 3. " -- "Set the 'g:ycm_server_python_interpreter' option to a Python 2 " -- "interpreter path." ) -- RunNotifyUserIfServerCrashed( { -- 'return_code': 5, -- 'expected_message': equal_to( message ) -- } ) -- -- --def YouCompleteMe_NotifyUserIfServerCrashed_Python3Core_test(): -- message = ( "The ycmd server SHUT DOWN (restart with ':YcmRestartServer'). " -- "YCM core library compiled for Python 3 but loaded in Python 2. " -- "Set the 'g:ycm_server_python_interpreter' option to a Python 3 " -- "interpreter path." ) -- RunNotifyUserIfServerCrashed( { -- 'return_code': 6, -- 'expected_message': equal_to( message ) -- } ) -- -- - def YouCompleteMe_NotifyUserIfServerCrashed_OutdatedCore_test(): - message = ( "The ycmd server SHUT DOWN (restart with ':YcmRestartServer'). " - "YCM core library too old; PLEASE RECOMPILE by running the " -diff --git a/python/ycm/unsafe_thread_pool_executor.py b/python/ycm/unsafe_thread_pool_executor.py -index e55dc018c..5baa11f2d 100644 ---- a/python/ycm/unsafe_thread_pool_executor.py -+++ b/python/ycm/unsafe_thread_pool_executor.py -@@ -6,7 +6,6 @@ - # (the Python Software Foundation License). - - --from __future__ import with_statement - import threading - import weakref - import sys -@@ -28,7 +27,7 @@ - # only send network requests). The YCM workload is one of those workloads where - # it's safe (the aforementioned network requests case). - --class _WorkItem( object ): -+class _WorkItem: - def __init__( self, future, fn, args, kwargs ): - self.future = future - self.fn = fn -diff --git a/python/ycm/vimsupport.py b/python/ycm/vimsupport.py -index 81ab12219..93d5b676b 100644 ---- a/python/ycm/vimsupport.py -+++ b/python/ycm/vimsupport.py -@@ -15,14 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- --from future.utils import iterkeys - import vim - import os - import json -@@ -321,8 +313,7 @@ def GetDiagnosticMatchPattern( line_num, - def LineAndColumnNumbersClamped( line_num, column_num ): - line_num = max( min( line_num, len( vim.current.buffer ) ), 1 ) - -- # Vim buffers are a list of byte objects on Python 2 but Unicode objects on -- # Python 3. -+ # Vim buffers are a list of Unicode objects on Python 3. - max_column = len( ToBytes( vim.current.buffer[ line_num - 1 ] ) ) - - return line_num, min( column_num, max_column ) -@@ -876,7 +867,7 @@ def ReplaceChunks( chunks, silent=False ): - chunks_by_file = _SortChunksByFile( chunks ) - - # We sort the file list simply to enable repeatable testing. -- sorted_file_list = sorted( iterkeys( chunks_by_file ) ) -+ sorted_file_list = sorted( chunks_by_file.keys() ) - - if not silent: - # Make sure the user is prepared to have her screen mutilated by the new -@@ -997,8 +988,7 @@ def ReplaceChunk( start, end, replacement_text, vim_buffer ): - # so we convert to bytes - replacement_lines = SplitLines( ToBytes( replacement_text ) ) - -- # NOTE: Vim buffers are a list of byte objects on Python 2 but unicode -- # objects on Python 3. -+ # NOTE: Vim buffers are a list of unicode objects on Python 3. - start_existing_text = ToBytes( vim_buffer[ start_line ] )[ : start_column ] - end_line_text = ToBytes( vim_buffer[ end_line ] ) - end_existing_text = end_line_text[ end_column : ] -diff --git a/python/ycm/youcompleteme.py b/python/ycm/youcompleteme.py -index 05da81c8d..8a8cf5ff7 100644 ---- a/python/ycm/youcompleteme.py -+++ b/python/ycm/youcompleteme.py -@@ -15,14 +15,6 @@ - # You should have received a copy of the GNU General Public License - # along with YouCompleteMe. If not, see . - --from __future__ import unicode_literals --from __future__ import print_function --from __future__ import division --from __future__ import absolute_import --# Not installing aliases from python-future; it's unreliable and slow. --from builtins import * # noqa -- --from future.utils import iteritems, itervalues - import base64 - import json - import logging -@@ -85,17 +77,12 @@ def PatchNoProxy(): - CORE_MISSING_MESSAGE = ( - 'YCM core library not detected; you need to compile YCM before using it. ' - 'Follow the instructions in the documentation.' ) --CORE_PYTHON2_MESSAGE = ( -- "YCM core library compiled for Python 2 but loaded in Python 3. " -- "Set the 'g:ycm_server_python_interpreter' option to a Python 2 " -- "interpreter path." ) --CORE_PYTHON3_MESSAGE = ( -- "YCM core library compiled for Python 3 but loaded in Python 2. " -- "Set the 'g:ycm_server_python_interpreter' option to a Python 3 " -- "interpreter path." ) - CORE_OUTDATED_MESSAGE = ( - 'YCM core library too old; PLEASE RECOMPILE by running the install.py ' - 'script. See the documentation for more details.' ) -+NO_PYTHON2_SUPPORT_MESSAGE = ( -+ 'YCM has dropped support for python2. ' -+ 'You need to recompile it with python3 instead.' ) - SERVER_IDLE_SUICIDE_SECONDS = 1800 # 30 minutes - CLIENT_LOGFILE_FORMAT = 'ycm_' - SERVER_LOGFILE_FORMAT = 'ycmd_{port}_{std}_' -@@ -105,7 +92,7 @@ def PatchNoProxy(): - HANDLE_FLAG_INHERIT = 0x00000001 - - --class YouCompleteMe( object ): -+class YouCompleteMe: - def __init__( self ): - self._available_completers = {} - self._user_options = None -@@ -261,17 +248,16 @@ def NotifyUserIfServerCrashed( self ): - error_message = CORE_UNEXPECTED_MESSAGE.format( logfile = logfile ) - elif return_code == 4: - error_message = CORE_MISSING_MESSAGE -- elif return_code == 5: -- error_message = CORE_PYTHON2_MESSAGE -- elif return_code == 6: -- error_message = CORE_PYTHON3_MESSAGE - elif return_code == 7: - error_message = CORE_OUTDATED_MESSAGE -+ elif return_code == 8: -+ error_message = NO_PYTHON2_SUPPORT_MESSAGE - else: - error_message = EXIT_CODE_UNEXPECTED_MESSAGE.format( code = return_code, - logfile = logfile ) - -- error_message = SERVER_SHUTDOWN_MESSAGE + ' ' + error_message -+ if return_code != 8: -+ error_message = SERVER_SHUTDOWN_MESSAGE + ' ' + error_message - self._logger.error( error_message ) - vimsupport.PostVimMessage( error_message ) - -@@ -502,7 +488,7 @@ def OnPeriodicTick( self ): - not self._message_poll_requests[ filetype ].Poll( self ) ): - self._message_poll_requests[ filetype ] = None - -- return any( itervalues( self._message_poll_requests ) ) -+ return any( self._message_poll_requests.values() ) - - - def OnFileReadyToParse( self ): -@@ -819,5 +805,5 @@ def _AddUltiSnipsDataIfNeeded( self, extra_data ): - extra_data[ 'ultisnips_snippets' ] = [ - { 'trigger': trigger, - 'description': snippet[ 'description' ] } -- for trigger, snippet in iteritems( snippets ) -+ for trigger, snippet in snippets.items() - ] -diff --git a/test/README.md b/test/README.md -index 0edc0a43a..e109b4fc3 100644 ---- a/test/README.md -+++ b/test/README.md -@@ -8,8 +8,6 @@ your machine. - - * Make sure you have docker installed (duh) - * Run `./docker/manual/run`. -- * This will use a Vim build with python 3 -- * If you want python2, run `./docker/manual/run --py 2` - * You should now be in the container. Your YCM checkout is now mounted in - `$HOME/YouCompleteMe` - * Run the following setup: -@@ -248,15 +246,13 @@ To get a local summary: - - # Docker - --We generate and push 4 containers: -+We generate and push 2 containers: - - * `youcompleteme/ycm-vim-py3:test` and `youcompleteme/ycm-vim-py3:manual` --* `youcompleteme/ycm-vim-py2:test` and `youcompleteme/ycm-vim-py2:manual` - - The `:test` tags are the containers that are used by Azure pipelines to run the - tests and contains essentially Ubuntu LTS + the YCM dependencies and a build of --Vim at a specific version built with either python3 (`-py3`) or python 2 --(`-py2`) support.. -+Vim at a specific version built with python3 (`-py3`) support. - - The `:manual` tags extend the `:test` tags with a user account that largely - matches the one created by Azure to run our tests. It also installs a basic -diff --git a/test/docker/ci/push b/test/docker/ci/push -index e08178b72..31a8481d9 100755 ---- a/test/docker/ci/push -+++ b/test/docker/ci/push -@@ -2,5 +2,4 @@ - - set -e - --docker push youcompleteme/ycm-vim-py2:test - docker push youcompleteme/ycm-vim-py3:test -diff --git a/test/docker/ci/rebuild b/test/docker/ci/rebuild -index 1363e3e25..6b384ad04 100755 ---- a/test/docker/ci/rebuild -+++ b/test/docker/ci/rebuild -@@ -8,9 +8,6 @@ else - OPTS="--no-cache" - fi - --docker build ${OPTS} -t youcompleteme/ycm-vim-py2:test \ -- --build-arg YCM_VIM_PYTHON=python \ -- image/ - docker build ${OPTS} -t youcompleteme/ycm-vim-py3:test \ - --build-arg YCM_VIM_PYTHON=python3 \ - image/ -diff --git a/test/docker/manual/push b/test/docker/manual/push -index bfe60c2d3..ee32addfc 100755 ---- a/test/docker/manual/push -+++ b/test/docker/manual/push -@@ -2,5 +2,4 @@ - - set -e - --docker push youcompleteme/ycm-vim-py2:manual - docker push youcompleteme/ycm-vim-py3:manual -diff --git a/test/docker/manual/rebuild b/test/docker/manual/rebuild -index c956d657d..9c7f39166 100755 ---- a/test/docker/manual/rebuild -+++ b/test/docker/manual/rebuild -@@ -8,9 +8,6 @@ else - OPTS="--no-cache" - fi - --docker build ${OPTS} -t youcompleteme/ycm-vim-py2:manual \ -- --build-arg YCM_PYTHON=py2 \ -- image/ - docker build ${OPTS} -t youcompleteme/ycm-vim-py3:manual \ - --build-arg YCM_PYTHON=py3 \ - image/ -diff --git a/third_party/pythonfutures/CHANGES b/third_party/pythonfutures/CHANGES -deleted file mode 100755 -index 81df636f2..000000000 ---- a/third_party/pythonfutures/CHANGES -+++ /dev/null -@@ -1,44 +0,0 @@ --2.1.4 --===== -- --- Ported the library again from Python 3.2.5 to get the latest bug fixes -- -- --2.1.3 --===== -- --- Fixed race condition in wait(return_when=ALL_COMPLETED) -- (http://bugs.python.org/issue14406) -- thanks Ralf Schmitt --- Added missing setUp() methods to several test classes -- -- --2.1.2 --===== -- --- Fixed installation problem on Python 3.1 -- -- --2.1.1 --===== -- --- Fixed missing 'concurrent' package declaration in setup.py -- -- --2.1 --=== -- --- Moved the code from the 'futures' package to 'concurrent.futures' to provide -- a drop in backport that matches the code in Python 3.2 standard library --- Deprecated the old 'futures' package -- -- --2.0 --=== -- --- Changed implementation to match PEP 3148 -- -- --1.0 --=== -- --Initial release. -diff --git a/third_party/pythonfutures/LICENSE b/third_party/pythonfutures/LICENSE -deleted file mode 100755 -index c430db0f1..000000000 ---- a/third_party/pythonfutures/LICENSE -+++ /dev/null -@@ -1,21 +0,0 @@ --Copyright 2009 Brian Quinlan. All rights reserved. -- --Redistribution and use in source and binary forms, with or without modification, --are permitted provided that the following conditions are met: -- -- 1. Redistributions of source code must retain the above copyright notice, -- this list of conditions and the following disclaimer. -- 2. Redistributions in binary form must reproduce the above copyright notice, -- this list of conditions and the following disclaimer in the documentation -- and/or other materials provided with the distribution. -- --THIS SOFTWARE IS PROVIDED BY BRIAN QUINLAN "AS IS" AND ANY EXPRESS OR IMPLIED --WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF --MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT --HALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, --INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT --LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR --PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF --LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE --OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF --ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -\ No newline at end of file -diff --git a/third_party/pythonfutures/concurrent/__init__.py b/third_party/pythonfutures/concurrent/__init__.py -deleted file mode 100755 -index b36383a61..000000000 ---- a/third_party/pythonfutures/concurrent/__init__.py -+++ /dev/null -@@ -1,3 +0,0 @@ --from pkgutil import extend_path -- --__path__ = extend_path(__path__, __name__) -diff --git a/third_party/pythonfutures/concurrent/futures/__init__.py b/third_party/pythonfutures/concurrent/futures/__init__.py -deleted file mode 100755 -index b5231f8aa..000000000 ---- a/third_party/pythonfutures/concurrent/futures/__init__.py -+++ /dev/null -@@ -1,18 +0,0 @@ --# Copyright 2009 Brian Quinlan. All Rights Reserved. --# Licensed to PSF under a Contributor Agreement. -- --"""Execute computations asynchronously using threads or processes.""" -- --__author__ = 'Brian Quinlan (brian@sweetapp.com)' -- --from concurrent.futures._base import (FIRST_COMPLETED, -- FIRST_EXCEPTION, -- ALL_COMPLETED, -- CancelledError, -- TimeoutError, -- Future, -- Executor, -- wait, -- as_completed) --from concurrent.futures.process import ProcessPoolExecutor --from concurrent.futures.thread import ThreadPoolExecutor -diff --git a/third_party/pythonfutures/concurrent/futures/_base.py b/third_party/pythonfutures/concurrent/futures/_base.py -deleted file mode 100755 -index 8ed69b7d9..000000000 ---- a/third_party/pythonfutures/concurrent/futures/_base.py -+++ /dev/null -@@ -1,574 +0,0 @@ --# Copyright 2009 Brian Quinlan. All Rights Reserved. --# Licensed to PSF under a Contributor Agreement. -- --from __future__ import with_statement --import logging --import threading --import time -- --try: -- from collections import namedtuple --except ImportError: -- from concurrent.futures._compat import namedtuple -- --__author__ = 'Brian Quinlan (brian@sweetapp.com)' -- --FIRST_COMPLETED = 'FIRST_COMPLETED' --FIRST_EXCEPTION = 'FIRST_EXCEPTION' --ALL_COMPLETED = 'ALL_COMPLETED' --_AS_COMPLETED = '_AS_COMPLETED' -- --# Possible future states (for internal use by the futures package). --PENDING = 'PENDING' --RUNNING = 'RUNNING' --# The future was cancelled by the user... --CANCELLED = 'CANCELLED' --# ...and _Waiter.add_cancelled() was called by a worker. --CANCELLED_AND_NOTIFIED = 'CANCELLED_AND_NOTIFIED' --FINISHED = 'FINISHED' -- --_FUTURE_STATES = [ -- PENDING, -- RUNNING, -- CANCELLED, -- CANCELLED_AND_NOTIFIED, -- FINISHED --] -- --_STATE_TO_DESCRIPTION_MAP = { -- PENDING: "pending", -- RUNNING: "running", -- CANCELLED: "cancelled", -- CANCELLED_AND_NOTIFIED: "cancelled", -- FINISHED: "finished" --} -- --# Logger for internal use by the futures package. --LOGGER = logging.getLogger("concurrent.futures") -- --class Error(Exception): -- """Base class for all future-related exceptions.""" -- pass -- --class CancelledError(Error): -- """The Future was cancelled.""" -- pass -- --class TimeoutError(Error): -- """The operation exceeded the given deadline.""" -- pass -- --class _Waiter(object): -- """Provides the event that wait() and as_completed() block on.""" -- def __init__(self): -- self.event = threading.Event() -- self.finished_futures = [] -- -- def add_result(self, future): -- self.finished_futures.append(future) -- -- def add_exception(self, future): -- self.finished_futures.append(future) -- -- def add_cancelled(self, future): -- self.finished_futures.append(future) -- --class _AsCompletedWaiter(_Waiter): -- """Used by as_completed().""" -- -- def __init__(self): -- super(_AsCompletedWaiter, self).__init__() -- self.lock = threading.Lock() -- -- def add_result(self, future): -- with self.lock: -- super(_AsCompletedWaiter, self).add_result(future) -- self.event.set() -- -- def add_exception(self, future): -- with self.lock: -- super(_AsCompletedWaiter, self).add_exception(future) -- self.event.set() -- -- def add_cancelled(self, future): -- with self.lock: -- super(_AsCompletedWaiter, self).add_cancelled(future) -- self.event.set() -- --class _FirstCompletedWaiter(_Waiter): -- """Used by wait(return_when=FIRST_COMPLETED).""" -- -- def add_result(self, future): -- super(_FirstCompletedWaiter, self).add_result(future) -- self.event.set() -- -- def add_exception(self, future): -- super(_FirstCompletedWaiter, self).add_exception(future) -- self.event.set() -- -- def add_cancelled(self, future): -- super(_FirstCompletedWaiter, self).add_cancelled(future) -- self.event.set() -- --class _AllCompletedWaiter(_Waiter): -- """Used by wait(return_when=FIRST_EXCEPTION and ALL_COMPLETED).""" -- -- def __init__(self, num_pending_calls, stop_on_exception): -- self.num_pending_calls = num_pending_calls -- self.stop_on_exception = stop_on_exception -- self.lock = threading.Lock() -- super(_AllCompletedWaiter, self).__init__() -- -- def _decrement_pending_calls(self): -- with self.lock: -- self.num_pending_calls -= 1 -- if not self.num_pending_calls: -- self.event.set() -- -- def add_result(self, future): -- super(_AllCompletedWaiter, self).add_result(future) -- self._decrement_pending_calls() -- -- def add_exception(self, future): -- super(_AllCompletedWaiter, self).add_exception(future) -- if self.stop_on_exception: -- self.event.set() -- else: -- self._decrement_pending_calls() -- -- def add_cancelled(self, future): -- super(_AllCompletedWaiter, self).add_cancelled(future) -- self._decrement_pending_calls() -- --class _AcquireFutures(object): -- """A context manager that does an ordered acquire of Future conditions.""" -- -- def __init__(self, futures): -- self.futures = sorted(futures, key=id) -- -- def __enter__(self): -- for future in self.futures: -- future._condition.acquire() -- -- def __exit__(self, *args): -- for future in self.futures: -- future._condition.release() -- --def _create_and_install_waiters(fs, return_when): -- if return_when == _AS_COMPLETED: -- waiter = _AsCompletedWaiter() -- elif return_when == FIRST_COMPLETED: -- waiter = _FirstCompletedWaiter() -- else: -- pending_count = sum( -- f._state not in [CANCELLED_AND_NOTIFIED, FINISHED] for f in fs) -- -- if return_when == FIRST_EXCEPTION: -- waiter = _AllCompletedWaiter(pending_count, stop_on_exception=True) -- elif return_when == ALL_COMPLETED: -- waiter = _AllCompletedWaiter(pending_count, stop_on_exception=False) -- else: -- raise ValueError("Invalid return condition: %r" % return_when) -- -- for f in fs: -- f._waiters.append(waiter) -- -- return waiter -- --def as_completed(fs, timeout=None): -- """An iterator over the given futures that yields each as it completes. -- -- Args: -- fs: The sequence of Futures (possibly created by different Executors) to -- iterate over. -- timeout: The maximum number of seconds to wait. If None, then there -- is no limit on the wait time. -- -- Returns: -- An iterator that yields the given Futures as they complete (finished or -- cancelled). -- -- Raises: -- TimeoutError: If the entire result iterator could not be generated -- before the given timeout. -- """ -- if timeout is not None: -- end_time = timeout + time.time() -- -- with _AcquireFutures(fs): -- finished = set( -- f for f in fs -- if f._state in [CANCELLED_AND_NOTIFIED, FINISHED]) -- pending = set(fs) - finished -- waiter = _create_and_install_waiters(fs, _AS_COMPLETED) -- -- try: -- for future in finished: -- yield future -- -- while pending: -- if timeout is None: -- wait_timeout = None -- else: -- wait_timeout = end_time - time.time() -- if wait_timeout < 0: -- raise TimeoutError( -- '%d (of %d) futures unfinished' % ( -- len(pending), len(fs))) -- -- waiter.event.wait(wait_timeout) -- -- with waiter.lock: -- finished = waiter.finished_futures -- waiter.finished_futures = [] -- waiter.event.clear() -- -- for future in finished: -- yield future -- pending.remove(future) -- -- finally: -- for f in fs: -- f._waiters.remove(waiter) -- --DoneAndNotDoneFutures = namedtuple( -- 'DoneAndNotDoneFutures', 'done not_done') --def wait(fs, timeout=None, return_when=ALL_COMPLETED): -- """Wait for the futures in the given sequence to complete. -- -- Args: -- fs: The sequence of Futures (possibly created by different Executors) to -- wait upon. -- timeout: The maximum number of seconds to wait. If None, then there -- is no limit on the wait time. -- return_when: Indicates when this function should return. The options -- are: -- -- FIRST_COMPLETED - Return when any future finishes or is -- cancelled. -- FIRST_EXCEPTION - Return when any future finishes by raising an -- exception. If no future raises an exception -- then it is equivalent to ALL_COMPLETED. -- ALL_COMPLETED - Return when all futures finish or are cancelled. -- -- Returns: -- A named 2-tuple of sets. The first set, named 'done', contains the -- futures that completed (is finished or cancelled) before the wait -- completed. The second set, named 'not_done', contains uncompleted -- futures. -- """ -- with _AcquireFutures(fs): -- done = set(f for f in fs -- if f._state in [CANCELLED_AND_NOTIFIED, FINISHED]) -- not_done = set(fs) - done -- -- if (return_when == FIRST_COMPLETED) and done: -- return DoneAndNotDoneFutures(done, not_done) -- elif (return_when == FIRST_EXCEPTION) and done: -- if any(f for f in done -- if not f.cancelled() and f.exception() is not None): -- return DoneAndNotDoneFutures(done, not_done) -- -- if len(done) == len(fs): -- return DoneAndNotDoneFutures(done, not_done) -- -- waiter = _create_and_install_waiters(fs, return_when) -- -- waiter.event.wait(timeout) -- for f in fs: -- f._waiters.remove(waiter) -- -- done.update(waiter.finished_futures) -- return DoneAndNotDoneFutures(done, set(fs) - done) -- --class Future(object): -- """Represents the result of an asynchronous computation.""" -- -- def __init__(self): -- """Initializes the future. Should not be called by clients.""" -- self._condition = threading.Condition() -- self._state = PENDING -- self._result = None -- self._exception = None -- self._waiters = [] -- self._done_callbacks = [] -- -- def _invoke_callbacks(self): -- for callback in self._done_callbacks: -- try: -- callback(self) -- except Exception: -- LOGGER.exception('exception calling callback for %r', self) -- -- def __repr__(self): -- with self._condition: -- if self._state == FINISHED: -- if self._exception: -- return '' % ( -- hex(id(self)), -- _STATE_TO_DESCRIPTION_MAP[self._state], -- self._exception.__class__.__name__) -- else: -- return '' % ( -- hex(id(self)), -- _STATE_TO_DESCRIPTION_MAP[self._state], -- self._result.__class__.__name__) -- return '' % ( -- hex(id(self)), -- _STATE_TO_DESCRIPTION_MAP[self._state]) -- -- def cancel(self): -- """Cancel the future if possible. -- -- Returns True if the future was cancelled, False otherwise. A future -- cannot be cancelled if it is running or has already completed. -- """ -- with self._condition: -- if self._state in [RUNNING, FINISHED]: -- return False -- -- if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]: -- return True -- -- self._state = CANCELLED -- self._condition.notify_all() -- -- self._invoke_callbacks() -- return True -- -- def cancelled(self): -- """Return True if the future has cancelled.""" -- with self._condition: -- return self._state in [CANCELLED, CANCELLED_AND_NOTIFIED] -- -- def running(self): -- """Return True if the future is currently executing.""" -- with self._condition: -- return self._state == RUNNING -- -- def done(self): -- """Return True of the future was cancelled or finished executing.""" -- with self._condition: -- return self._state in [CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED] -- -- def __get_result(self): -- if self._exception: -- raise self._exception -- else: -- return self._result -- -- def add_done_callback(self, fn): -- """Attaches a callable that will be called when the future finishes. -- -- Args: -- fn: A callable that will be called with this future as its only -- argument when the future completes or is cancelled. The callable -- will always be called by a thread in the same process in which -- it was added. If the future has already completed or been -- cancelled then the callable will be called immediately. These -- callables are called in the order that they were added. -- """ -- with self._condition: -- if self._state not in [CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED]: -- self._done_callbacks.append(fn) -- return -- fn(self) -- -- def result(self, timeout=None): -- """Return the result of the call that the future represents. -- -- Args: -- timeout: The number of seconds to wait for the result if the future -- isn't done. If None, then there is no limit on the wait time. -- -- Returns: -- The result of the call that the future represents. -- -- Raises: -- CancelledError: If the future was cancelled. -- TimeoutError: If the future didn't finish executing before the given -- timeout. -- Exception: If the call raised then that exception will be raised. -- """ -- with self._condition: -- if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]: -- raise CancelledError() -- elif self._state == FINISHED: -- return self.__get_result() -- -- self._condition.wait(timeout) -- -- if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]: -- raise CancelledError() -- elif self._state == FINISHED: -- return self.__get_result() -- else: -- raise TimeoutError() -- -- def exception(self, timeout=None): -- """Return the exception raised by the call that the future represents. -- -- Args: -- timeout: The number of seconds to wait for the exception if the -- future isn't done. If None, then there is no limit on the wait -- time. -- -- Returns: -- The exception raised by the call that the future represents or None -- if the call completed without raising. -- -- Raises: -- CancelledError: If the future was cancelled. -- TimeoutError: If the future didn't finish executing before the given -- timeout. -- """ -- -- with self._condition: -- if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]: -- raise CancelledError() -- elif self._state == FINISHED: -- return self._exception -- -- self._condition.wait(timeout) -- -- if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]: -- raise CancelledError() -- elif self._state == FINISHED: -- return self._exception -- else: -- raise TimeoutError() -- -- # The following methods should only be used by Executors and in tests. -- def set_running_or_notify_cancel(self): -- """Mark the future as running or process any cancel notifications. -- -- Should only be used by Executor implementations and unit tests. -- -- If the future has been cancelled (cancel() was called and returned -- True) then any threads waiting on the future completing (though calls -- to as_completed() or wait()) are notified and False is returned. -- -- If the future was not cancelled then it is put in the running state -- (future calls to running() will return True) and True is returned. -- -- This method should be called by Executor implementations before -- executing the work associated with this future. If this method returns -- False then the work should not be executed. -- -- Returns: -- False if the Future was cancelled, True otherwise. -- -- Raises: -- RuntimeError: if this method was already called or if set_result() -- or set_exception() was called. -- """ -- with self._condition: -- if self._state == CANCELLED: -- self._state = CANCELLED_AND_NOTIFIED -- for waiter in self._waiters: -- waiter.add_cancelled(self) -- # self._condition.notify_all() is not necessary because -- # self.cancel() triggers a notification. -- return False -- elif self._state == PENDING: -- self._state = RUNNING -- return True -- else: -- LOGGER.critical('Future %s in unexpected state: %s', -- id(self.future), -- self.future._state) -- raise RuntimeError('Future in unexpected state') -- -- def set_result(self, result): -- """Sets the return value of work associated with the future. -- -- Should only be used by Executor implementations and unit tests. -- """ -- with self._condition: -- self._result = result -- self._state = FINISHED -- for waiter in self._waiters: -- waiter.add_result(self) -- self._condition.notify_all() -- self._invoke_callbacks() -- -- def set_exception(self, exception): -- """Sets the result of the future as being the given exception. -- -- Should only be used by Executor implementations and unit tests. -- """ -- with self._condition: -- self._exception = exception -- self._state = FINISHED -- for waiter in self._waiters: -- waiter.add_exception(self) -- self._condition.notify_all() -- self._invoke_callbacks() -- --class Executor(object): -- """This is an abstract base class for concrete asynchronous executors.""" -- -- def submit(self, fn, *args, **kwargs): -- """Submits a callable to be executed with the given arguments. -- -- Schedules the callable to be executed as fn(*args, **kwargs) and returns -- a Future instance representing the execution of the callable. -- -- Returns: -- A Future representing the given call. -- """ -- raise NotImplementedError() -- -- def map(self, fn, *iterables, **kwargs): -- """Returns a iterator equivalent to map(fn, iter). -- -- Args: -- fn: A callable that will take as many arguments as there are -- passed iterables. -- timeout: The maximum number of seconds to wait. If None, then there -- is no limit on the wait time. -- -- Returns: -- An iterator equivalent to: map(func, *iterables) but the calls may -- be evaluated out-of-order. -- -- Raises: -- TimeoutError: If the entire result iterator could not be generated -- before the given timeout. -- Exception: If fn(*args) raises for any values. -- """ -- timeout = kwargs.get('timeout') -- if timeout is not None: -- end_time = timeout + time.time() -- -- fs = [self.submit(fn, *args) for args in zip(*iterables)] -- -- try: -- for future in fs: -- if timeout is None: -- yield future.result() -- else: -- yield future.result(end_time - time.time()) -- finally: -- for future in fs: -- future.cancel() -- -- def shutdown(self, wait=True): -- """Clean-up the resources associated with the Executor. -- -- It is safe to call this method several times. Otherwise, no other -- methods can be called after this one. -- -- Args: -- wait: If True then shutdown will not return until all running -- futures have finished executing and the resources used by the -- executor have been reclaimed. -- """ -- pass -- -- def __enter__(self): -- return self -- -- def __exit__(self, exc_type, exc_val, exc_tb): -- self.shutdown(wait=True) -- return False -diff --git a/third_party/pythonfutures/concurrent/futures/_compat.py b/third_party/pythonfutures/concurrent/futures/_compat.py -deleted file mode 100755 -index 11462326b..000000000 ---- a/third_party/pythonfutures/concurrent/futures/_compat.py -+++ /dev/null -@@ -1,101 +0,0 @@ --from keyword import iskeyword as _iskeyword --from operator import itemgetter as _itemgetter --import sys as _sys -- -- --def namedtuple(typename, field_names): -- """Returns a new subclass of tuple with named fields. -- -- >>> Point = namedtuple('Point', 'x y') -- >>> Point.__doc__ # docstring for the new class -- 'Point(x, y)' -- >>> p = Point(11, y=22) # instantiate with positional args or keywords -- >>> p[0] + p[1] # indexable like a plain tuple -- 33 -- >>> x, y = p # unpack like a regular tuple -- >>> x, y -- (11, 22) -- >>> p.x + p.y # fields also accessable by name -- 33 -- >>> d = p._asdict() # convert to a dictionary -- >>> d['x'] -- 11 -- >>> Point(**d) # convert from a dictionary -- Point(x=11, y=22) -- >>> p._replace(x=100) # _replace() is like str.replace() but targets named fields -- Point(x=100, y=22) -- -- """ -- -- # Parse and validate the field names. Validation serves two purposes, -- # generating informative error messages and preventing template injection attacks. -- if isinstance(field_names, basestring): -- field_names = field_names.replace(',', ' ').split() # names separated by whitespace and/or commas -- field_names = tuple(map(str, field_names)) -- for name in (typename,) + field_names: -- if not all(c.isalnum() or c=='_' for c in name): -- raise ValueError('Type names and field names can only contain alphanumeric characters and underscores: %r' % name) -- if _iskeyword(name): -- raise ValueError('Type names and field names cannot be a keyword: %r' % name) -- if name[0].isdigit(): -- raise ValueError('Type names and field names cannot start with a number: %r' % name) -- seen_names = set() -- for name in field_names: -- if name.startswith('_'): -- raise ValueError('Field names cannot start with an underscore: %r' % name) -- if name in seen_names: -- raise ValueError('Encountered duplicate field name: %r' % name) -- seen_names.add(name) -- -- # Create and fill-in the class template -- numfields = len(field_names) -- argtxt = repr(field_names).replace("'", "")[1:-1] # tuple repr without parens or quotes -- reprtxt = ', '.join('%s=%%r' % name for name in field_names) -- dicttxt = ', '.join('%r: t[%d]' % (name, pos) for pos, name in enumerate(field_names)) -- template = '''class %(typename)s(tuple): -- '%(typename)s(%(argtxt)s)' \n -- __slots__ = () \n -- _fields = %(field_names)r \n -- def __new__(_cls, %(argtxt)s): -- return _tuple.__new__(_cls, (%(argtxt)s)) \n -- @classmethod -- def _make(cls, iterable, new=tuple.__new__, len=len): -- 'Make a new %(typename)s object from a sequence or iterable' -- result = new(cls, iterable) -- if len(result) != %(numfields)d: -- raise TypeError('Expected %(numfields)d arguments, got %%d' %% len(result)) -- return result \n -- def __repr__(self): -- return '%(typename)s(%(reprtxt)s)' %% self \n -- def _asdict(t): -- 'Return a new dict which maps field names to their values' -- return {%(dicttxt)s} \n -- def _replace(_self, **kwds): -- 'Return a new %(typename)s object replacing specified fields with new values' -- result = _self._make(map(kwds.pop, %(field_names)r, _self)) -- if kwds: -- raise ValueError('Got unexpected field names: %%r' %% kwds.keys()) -- return result \n -- def __getnewargs__(self): -- return tuple(self) \n\n''' % locals() -- for i, name in enumerate(field_names): -- template += ' %s = _property(_itemgetter(%d))\n' % (name, i) -- -- # Execute the template string in a temporary namespace and -- # support tracing utilities by setting a value for frame.f_globals['__name__'] -- namespace = dict(_itemgetter=_itemgetter, __name__='namedtuple_%s' % typename, -- _property=property, _tuple=tuple) -- try: -- exec(template, namespace) -- except SyntaxError: -- e = _sys.exc_info()[1] -- raise SyntaxError(e.message + ':\n' + template) -- result = namespace[typename] -- -- # For pickling to work, the __module__ variable needs to be set to the frame -- # where the named tuple is created. Bypass this step in enviroments where -- # sys._getframe is not defined (Jython for example). -- if hasattr(_sys, '_getframe'): -- result.__module__ = _sys._getframe(1).f_globals.get('__name__', '__main__') -- -- return result -diff --git a/third_party/pythonfutures/concurrent/futures/process.py b/third_party/pythonfutures/concurrent/futures/process.py -deleted file mode 100755 -index 98684f8e8..000000000 ---- a/third_party/pythonfutures/concurrent/futures/process.py -+++ /dev/null -@@ -1,363 +0,0 @@ --# Copyright 2009 Brian Quinlan. All Rights Reserved. --# Licensed to PSF under a Contributor Agreement. -- --"""Implements ProcessPoolExecutor. -- --The follow diagram and text describe the data-flow through the system: -- --|======================= In-process =====================|== Out-of-process ==| -- --+----------+ +----------+ +--------+ +-----------+ +---------+ --| | => | Work Ids | => | | => | Call Q | => | | --| | +----------+ | | +-----------+ | | --| | | ... | | | | ... | | | --| | | 6 | | | | 5, call() | | | --| | | 7 | | | | ... | | | --| Process | | ... | | Local | +-----------+ | Process | --| Pool | +----------+ | Worker | | #1..n | --| Executor | | Thread | | | --| | +----------- + | | +-----------+ | | --| | <=> | Work Items | <=> | | <= | Result Q | <= | | --| | +------------+ | | +-----------+ | | --| | | 6: call() | | | | ... | | | --| | | future | | | | 4, result | | | --| | | ... | | | | 3, except | | | --+----------+ +------------+ +--------+ +-----------+ +---------+ -- --Executor.submit() called: --- creates a uniquely numbered _WorkItem and adds it to the "Work Items" dict --- adds the id of the _WorkItem to the "Work Ids" queue -- --Local worker thread: --- reads work ids from the "Work Ids" queue and looks up the corresponding -- WorkItem from the "Work Items" dict: if the work item has been cancelled then -- it is simply removed from the dict, otherwise it is repackaged as a -- _CallItem and put in the "Call Q". New _CallItems are put in the "Call Q" -- until "Call Q" is full. NOTE: the size of the "Call Q" is kept small because -- calls placed in the "Call Q" can no longer be cancelled with Future.cancel(). --- reads _ResultItems from "Result Q", updates the future stored in the -- "Work Items" dict and deletes the dict entry -- --Process #1..n: --- reads _CallItems from "Call Q", executes the calls, and puts the resulting -- _ResultItems in "Request Q" --""" -- --from __future__ import with_statement --import atexit --import multiprocessing --import threading --import weakref --import sys -- --from concurrent.futures import _base -- --try: -- import queue --except ImportError: -- import Queue as queue -- --__author__ = 'Brian Quinlan (brian@sweetapp.com)' -- --# Workers are created as daemon threads and processes. This is done to allow the --# interpreter to exit when there are still idle processes in a --# ProcessPoolExecutor's process pool (i.e. shutdown() was not called). However, --# allowing workers to die with the interpreter has two undesirable properties: --# - The workers would still be running during interpretor shutdown, --# meaning that they would fail in unpredictable ways. --# - The workers could be killed while evaluating a work item, which could --# be bad if the callable being evaluated has external side-effects e.g. --# writing to a file. --# --# To work around this problem, an exit handler is installed which tells the --# workers to exit when their work queues are empty and then waits until the --# threads/processes finish. -- --_threads_queues = weakref.WeakKeyDictionary() --_shutdown = False -- --def _python_exit(): -- global _shutdown -- _shutdown = True -- items = list(_threads_queues.items()) -- for t, q in items: -- q.put(None) -- for t, q in items: -- t.join() -- --# Controls how many more calls than processes will be queued in the call queue. --# A smaller number will mean that processes spend more time idle waiting for --# work while a larger number will make Future.cancel() succeed less frequently --# (Futures in the call queue cannot be cancelled). --EXTRA_QUEUED_CALLS = 1 -- --class _WorkItem(object): -- def __init__(self, future, fn, args, kwargs): -- self.future = future -- self.fn = fn -- self.args = args -- self.kwargs = kwargs -- --class _ResultItem(object): -- def __init__(self, work_id, exception=None, result=None): -- self.work_id = work_id -- self.exception = exception -- self.result = result -- --class _CallItem(object): -- def __init__(self, work_id, fn, args, kwargs): -- self.work_id = work_id -- self.fn = fn -- self.args = args -- self.kwargs = kwargs -- --def _process_worker(call_queue, result_queue): -- """Evaluates calls from call_queue and places the results in result_queue. -- -- This worker is run in a separate process. -- -- Args: -- call_queue: A multiprocessing.Queue of _CallItems that will be read and -- evaluated by the worker. -- result_queue: A multiprocessing.Queue of _ResultItems that will written -- to by the worker. -- shutdown: A multiprocessing.Event that will be set as a signal to the -- worker that it should exit when call_queue is empty. -- """ -- while True: -- call_item = call_queue.get(block=True) -- if call_item is None: -- # Wake up queue management thread -- result_queue.put(None) -- return -- try: -- r = call_item.fn(*call_item.args, **call_item.kwargs) -- except BaseException: -- e = sys.exc_info()[1] -- result_queue.put(_ResultItem(call_item.work_id, -- exception=e)) -- else: -- result_queue.put(_ResultItem(call_item.work_id, -- result=r)) -- --def _add_call_item_to_queue(pending_work_items, -- work_ids, -- call_queue): -- """Fills call_queue with _WorkItems from pending_work_items. -- -- This function never blocks. -- -- Args: -- pending_work_items: A dict mapping work ids to _WorkItems e.g. -- {5: <_WorkItem...>, 6: <_WorkItem...>, ...} -- work_ids: A queue.Queue of work ids e.g. Queue([5, 6, ...]). Work ids -- are consumed and the corresponding _WorkItems from -- pending_work_items are transformed into _CallItems and put in -- call_queue. -- call_queue: A multiprocessing.Queue that will be filled with _CallItems -- derived from _WorkItems. -- """ -- while True: -- if call_queue.full(): -- return -- try: -- work_id = work_ids.get(block=False) -- except queue.Empty: -- return -- else: -- work_item = pending_work_items[work_id] -- -- if work_item.future.set_running_or_notify_cancel(): -- call_queue.put(_CallItem(work_id, -- work_item.fn, -- work_item.args, -- work_item.kwargs), -- block=True) -- else: -- del pending_work_items[work_id] -- continue -- --def _queue_management_worker(executor_reference, -- processes, -- pending_work_items, -- work_ids_queue, -- call_queue, -- result_queue): -- """Manages the communication between this process and the worker processes. -- -- This function is run in a local thread. -- -- Args: -- executor_reference: A weakref.ref to the ProcessPoolExecutor that owns -- this thread. Used to determine if the ProcessPoolExecutor has been -- garbage collected and that this function can exit. -- process: A list of the multiprocessing.Process instances used as -- workers. -- pending_work_items: A dict mapping work ids to _WorkItems e.g. -- {5: <_WorkItem...>, 6: <_WorkItem...>, ...} -- work_ids_queue: A queue.Queue of work ids e.g. Queue([5, 6, ...]). -- call_queue: A multiprocessing.Queue that will be filled with _CallItems -- derived from _WorkItems for processing by the process workers. -- result_queue: A multiprocessing.Queue of _ResultItems generated by the -- process workers. -- """ -- nb_shutdown_processes = [0] -- def shutdown_one_process(): -- """Tell a worker to terminate, which will in turn wake us again""" -- call_queue.put(None) -- nb_shutdown_processes[0] += 1 -- while True: -- _add_call_item_to_queue(pending_work_items, -- work_ids_queue, -- call_queue) -- -- result_item = result_queue.get(block=True) -- if result_item is not None: -- work_item = pending_work_items[result_item.work_id] -- del pending_work_items[result_item.work_id] -- -- if result_item.exception: -- work_item.future.set_exception(result_item.exception) -- else: -- work_item.future.set_result(result_item.result) -- # Check whether we should start shutting down. -- executor = executor_reference() -- # No more work items can be added if: -- # - The interpreter is shutting down OR -- # - The executor that owns this worker has been collected OR -- # - The executor that owns this worker has been shutdown. -- if _shutdown or executor is None or executor._shutdown_thread: -- # Since no new work items can be added, it is safe to shutdown -- # this thread if there are no pending work items. -- if not pending_work_items: -- while nb_shutdown_processes[0] < len(processes): -- shutdown_one_process() -- # If .join() is not called on the created processes then -- # some multiprocessing.Queue methods may deadlock on Mac OS -- # X. -- for p in processes: -- p.join() -- call_queue.close() -- return -- del executor -- --_system_limits_checked = False --_system_limited = None --def _check_system_limits(): -- global _system_limits_checked, _system_limited -- if _system_limits_checked: -- if _system_limited: -- raise NotImplementedError(_system_limited) -- _system_limits_checked = True -- try: -- import os -- nsems_max = os.sysconf("SC_SEM_NSEMS_MAX") -- except (AttributeError, ValueError): -- # sysconf not available or setting not available -- return -- if nsems_max == -1: -- # indetermine limit, assume that limit is determined -- # by available memory only -- return -- if nsems_max >= 256: -- # minimum number of semaphores available -- # according to POSIX -- return -- _system_limited = "system provides too few semaphores (%d available, 256 necessary)" % nsems_max -- raise NotImplementedError(_system_limited) -- --class ProcessPoolExecutor(_base.Executor): -- def __init__(self, max_workers=None): -- """Initializes a new ProcessPoolExecutor instance. -- -- Args: -- max_workers: The maximum number of processes that can be used to -- execute the given calls. If None or not given then as many -- worker processes will be created as the machine has processors. -- """ -- _check_system_limits() -- -- if max_workers is None: -- self._max_workers = multiprocessing.cpu_count() -- else: -- self._max_workers = max_workers -- -- # Make the call queue slightly larger than the number of processes to -- # prevent the worker processes from idling. But don't make it too big -- # because futures in the call queue cannot be cancelled. -- self._call_queue = multiprocessing.Queue(self._max_workers + -- EXTRA_QUEUED_CALLS) -- self._result_queue = multiprocessing.Queue() -- self._work_ids = queue.Queue() -- self._queue_management_thread = None -- self._processes = set() -- -- # Shutdown is a two-step process. -- self._shutdown_thread = False -- self._shutdown_lock = threading.Lock() -- self._queue_count = 0 -- self._pending_work_items = {} -- -- def _start_queue_management_thread(self): -- # When the executor gets lost, the weakref callback will wake up -- # the queue management thread. -- def weakref_cb(_, q=self._result_queue): -- q.put(None) -- if self._queue_management_thread is None: -- self._queue_management_thread = threading.Thread( -- target=_queue_management_worker, -- args=(weakref.ref(self, weakref_cb), -- self._processes, -- self._pending_work_items, -- self._work_ids, -- self._call_queue, -- self._result_queue)) -- self._queue_management_thread.daemon = True -- self._queue_management_thread.start() -- _threads_queues[self._queue_management_thread] = self._result_queue -- -- def _adjust_process_count(self): -- for _ in range(len(self._processes), self._max_workers): -- p = multiprocessing.Process( -- target=_process_worker, -- args=(self._call_queue, -- self._result_queue)) -- p.start() -- self._processes.add(p) -- -- def submit(self, fn, *args, **kwargs): -- with self._shutdown_lock: -- if self._shutdown_thread: -- raise RuntimeError('cannot schedule new futures after shutdown') -- -- f = _base.Future() -- w = _WorkItem(f, fn, args, kwargs) -- -- self._pending_work_items[self._queue_count] = w -- self._work_ids.put(self._queue_count) -- self._queue_count += 1 -- # Wake up queue management thread -- self._result_queue.put(None) -- -- self._start_queue_management_thread() -- self._adjust_process_count() -- return f -- submit.__doc__ = _base.Executor.submit.__doc__ -- -- def shutdown(self, wait=True): -- with self._shutdown_lock: -- self._shutdown_thread = True -- if self._queue_management_thread: -- # Wake up queue management thread -- self._result_queue.put(None) -- if wait: -- self._queue_management_thread.join() -- # To reduce the risk of openning too many files, remove references to -- # objects that use file descriptors. -- self._queue_management_thread = None -- self._call_queue = None -- self._result_queue = None -- self._processes = None -- shutdown.__doc__ = _base.Executor.shutdown.__doc__ -- --atexit.register(_python_exit) -diff --git a/third_party/pythonfutures/concurrent/futures/thread.py b/third_party/pythonfutures/concurrent/futures/thread.py -deleted file mode 100755 -index a45959d3b..000000000 ---- a/third_party/pythonfutures/concurrent/futures/thread.py -+++ /dev/null -@@ -1,138 +0,0 @@ --# Copyright 2009 Brian Quinlan. All Rights Reserved. --# Licensed to PSF under a Contributor Agreement. -- --"""Implements ThreadPoolExecutor.""" -- --from __future__ import with_statement --import atexit --import threading --import weakref --import sys -- --from concurrent.futures import _base -- --try: -- import queue --except ImportError: -- import Queue as queue -- --__author__ = 'Brian Quinlan (brian@sweetapp.com)' -- --# Workers are created as daemon threads. This is done to allow the interpreter --# to exit when there are still idle threads in a ThreadPoolExecutor's thread --# pool (i.e. shutdown() was not called). However, allowing workers to die with --# the interpreter has two undesirable properties: --# - The workers would still be running during interpretor shutdown, --# meaning that they would fail in unpredictable ways. --# - The workers could be killed while evaluating a work item, which could --# be bad if the callable being evaluated has external side-effects e.g. --# writing to a file. --# --# To work around this problem, an exit handler is installed which tells the --# workers to exit when their work queues are empty and then waits until the --# threads finish. -- --_threads_queues = weakref.WeakKeyDictionary() --_shutdown = False -- --def _python_exit(): -- global _shutdown -- _shutdown = True -- items = list(_threads_queues.items()) -- for t, q in items: -- q.put(None) -- for t, q in items: -- t.join() -- --atexit.register(_python_exit) -- --class _WorkItem(object): -- def __init__(self, future, fn, args, kwargs): -- self.future = future -- self.fn = fn -- self.args = args -- self.kwargs = kwargs -- -- def run(self): -- if not self.future.set_running_or_notify_cancel(): -- return -- -- try: -- result = self.fn(*self.args, **self.kwargs) -- except BaseException: -- e = sys.exc_info()[1] -- self.future.set_exception(e) -- else: -- self.future.set_result(result) -- --def _worker(executor_reference, work_queue): -- try: -- while True: -- work_item = work_queue.get(block=True) -- if work_item is not None: -- work_item.run() -- continue -- executor = executor_reference() -- # Exit if: -- # - The interpreter is shutting down OR -- # - The executor that owns the worker has been collected OR -- # - The executor that owns the worker has been shutdown. -- if _shutdown or executor is None or executor._shutdown: -- # Notice other workers -- work_queue.put(None) -- return -- del executor -- except BaseException: -- _base.LOGGER.critical('Exception in worker', exc_info=True) -- --class ThreadPoolExecutor(_base.Executor): -- def __init__(self, max_workers): -- """Initializes a new ThreadPoolExecutor instance. -- -- Args: -- max_workers: The maximum number of threads that can be used to -- execute the given calls. -- """ -- self._max_workers = max_workers -- self._work_queue = queue.Queue() -- self._threads = set() -- self._shutdown = False -- self._shutdown_lock = threading.Lock() -- -- def submit(self, fn, *args, **kwargs): -- with self._shutdown_lock: -- if self._shutdown: -- raise RuntimeError('cannot schedule new futures after shutdown') -- -- f = _base.Future() -- w = _WorkItem(f, fn, args, kwargs) -- -- self._work_queue.put(w) -- self._adjust_thread_count() -- return f -- submit.__doc__ = _base.Executor.submit.__doc__ -- -- def _adjust_thread_count(self): -- # When the executor gets lost, the weakref callback will wake up -- # the worker threads. -- def weakref_cb(_, q=self._work_queue): -- q.put(None) -- # TODO(bquinlan): Should avoid creating new threads if there are more -- # idle threads than items in the work queue. -- if len(self._threads) < self._max_workers: -- t = threading.Thread(target=_worker, -- args=(weakref.ref(self, weakref_cb), -- self._work_queue)) -- t.daemon = True -- t.start() -- self._threads.add(t) -- _threads_queues[t] = self._work_queue -- -- def shutdown(self, wait=True): -- with self._shutdown_lock: -- self._shutdown = True -- self._work_queue.put(None) -- if wait: -- for t in self._threads: -- t.join() -- shutdown.__doc__ = _base.Executor.shutdown.__doc__ -diff --git a/third_party/pythonfutures/crawl.py b/third_party/pythonfutures/crawl.py -deleted file mode 100755 -index 86e0af7fe..000000000 ---- a/third_party/pythonfutures/crawl.py -+++ /dev/null -@@ -1,74 +0,0 @@ --"""Compare the speed of downloading URLs sequentially vs. using futures.""" -- --import functools --import time --import timeit --import sys -- --try: -- from urllib2 import urlopen --except ImportError: -- from urllib.request import urlopen -- --from concurrent.futures import (as_completed, ThreadPoolExecutor, -- ProcessPoolExecutor) -- --URLS = ['http://www.google.com/', -- 'http://www.apple.com/', -- 'http://www.ibm.com', -- 'http://www.thisurlprobablydoesnotexist.com', -- 'http://www.slashdot.org/', -- 'http://www.python.org/', -- 'http://www.bing.com/', -- 'http://www.facebook.com/', -- 'http://www.yahoo.com/', -- 'http://www.youtube.com/', -- 'http://www.blogger.com/'] -- --def load_url(url, timeout): -- kwargs = {'timeout': timeout} if sys.version_info >= (2, 6) else {} -- return urlopen(url, **kwargs).read() -- --def download_urls_sequential(urls, timeout=60): -- url_to_content = {} -- for url in urls: -- try: -- url_to_content[url] = load_url(url, timeout=timeout) -- except: -- pass -- return url_to_content -- --def download_urls_with_executor(urls, executor, timeout=60): -- try: -- url_to_content = {} -- future_to_url = dict((executor.submit(load_url, url, timeout), url) -- for url in urls) -- -- for future in as_completed(future_to_url): -- try: -- url_to_content[future_to_url[future]] = future.result() -- except: -- pass -- return url_to_content -- finally: -- executor.shutdown() -- --def main(): -- for name, fn in [('sequential', -- functools.partial(download_urls_sequential, URLS)), -- ('processes', -- functools.partial(download_urls_with_executor, -- URLS, -- ProcessPoolExecutor(10))), -- ('threads', -- functools.partial(download_urls_with_executor, -- URLS, -- ThreadPoolExecutor(10)))]: -- sys.stdout.write('%s: ' % name.ljust(12)) -- start = time.time() -- url_map = fn() -- sys.stdout.write('%.2f seconds (%d of %d downloaded)\n' % -- (time.time() - start, len(url_map), len(URLS))) -- --if __name__ == '__main__': -- main() -diff --git a/third_party/pythonfutures/docs/conf.py b/third_party/pythonfutures/docs/conf.py -deleted file mode 100755 -index 124cd5183..000000000 ---- a/third_party/pythonfutures/docs/conf.py -+++ /dev/null -@@ -1,194 +0,0 @@ --# -*- coding: utf-8 -*- --# --# futures documentation build configuration file, created by --# sphinx-quickstart on Wed Jun 3 19:35:34 2009. --# --# This file is execfile()d with the current directory set to its containing dir. --# --# Note that not all possible configuration values are present in this --# autogenerated file. --# --# All configuration values have a default; values that are commented out --# serve to show the default. -- --import sys, os -- --# If extensions (or modules to document with autodoc) are in another directory, --# add these directories to sys.path here. If the directory is relative to the --# documentation root, use os.path.abspath to make it absolute, like shown here. --#sys.path.append(os.path.abspath('.')) -- --# -- General configuration ----------------------------------------------------- -- --# Add any Sphinx extension module names here, as strings. They can be extensions --# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. --extensions = [] -- --# Add any paths that contain templates here, relative to this directory. --templates_path = ['_templates'] -- --# The suffix of source filenames. --source_suffix = '.rst' -- --# The encoding of source files. --#source_encoding = 'utf-8' -- --# The master toctree document. --master_doc = 'index' -- --# General information about the project. --project = u'futures' --copyright = u'2009-2011, Brian Quinlan' -- --# The version info for the project you're documenting, acts as replacement for --# |version| and |release|, also used in various other places throughout the --# built documents. --# --# The short X.Y version. --version = '2.1.3' --# The full version, including alpha/beta/rc tags. --release = '2.1.3' -- --# The language for content autogenerated by Sphinx. Refer to documentation --# for a list of supported languages. --#language = None -- --# There are two options for replacing |today|: either, you set today to some --# non-false value, then it is used: --#today = '' --# Else, today_fmt is used as the format for a strftime call. --#today_fmt = '%B %d, %Y' -- --# List of documents that shouldn't be included in the build. --#unused_docs = [] -- --# List of directories, relative to source directory, that shouldn't be searched --# for source files. --exclude_trees = ['_build'] -- --# The reST default role (used for this markup: `text`) to use for all documents. --#default_role = None -- --# If true, '()' will be appended to :func: etc. cross-reference text. --#add_function_parentheses = True -- --# If true, the current module name will be prepended to all description --# unit titles (such as .. function::). --#add_module_names = True -- --# If true, sectionauthor and moduleauthor directives will be shown in the --# output. They are ignored by default. --#show_authors = False -- --# The name of the Pygments (syntax highlighting) style to use. --pygments_style = 'sphinx' -- --# A list of ignored prefixes for module index sorting. --#modindex_common_prefix = [] -- -- --# -- Options for HTML output --------------------------------------------------- -- --# The theme to use for HTML and HTML Help pages. Major themes that come with --# Sphinx are currently 'default' and 'sphinxdoc'. --html_theme = 'default' -- --# Theme options are theme-specific and customize the look and feel of a theme --# further. For a list of options available for each theme, see the --# documentation. --#html_theme_options = {} -- --# Add any paths that contain custom themes here, relative to this directory. --#html_theme_path = [] -- --# The name for this set of Sphinx documents. If None, it defaults to --# " v documentation". --#html_title = None -- --# A shorter title for the navigation bar. Default is the same as html_title. --#html_short_title = None -- --# The name of an image file (relative to this directory) to place at the top --# of the sidebar. --#html_logo = None -- --# The name of an image file (within the static path) to use as favicon of the --# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 --# pixels large. --#html_favicon = None -- --# Add any paths that contain custom static files (such as style sheets) here, --# relative to this directory. They are copied after the builtin static files, --# so a file named "default.css" will overwrite the builtin "default.css". --html_static_path = ['_static'] -- --# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, --# using the given strftime format. --#html_last_updated_fmt = '%b %d, %Y' -- --# If true, SmartyPants will be used to convert quotes and dashes to --# typographically correct entities. --#html_use_smartypants = True -- --# Custom sidebar templates, maps document names to template names. --#html_sidebars = {} -- --# Additional templates that should be rendered to pages, maps page names to --# template names. --#html_additional_pages = {} -- --# If false, no module index is generated. --#html_use_modindex = True -- --# If false, no index is generated. --#html_use_index = True -- --# If true, the index is split into individual pages for each letter. --#html_split_index = False -- --# If true, links to the reST sources are added to the pages. --#html_show_sourcelink = True -- --# If true, an OpenSearch description file will be output, and all pages will --# contain a tag referring to it. The value of this option must be the --# base URL from which the finished HTML is served. --#html_use_opensearch = '' -- --# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). --#html_file_suffix = '' -- --# Output file base name for HTML help builder. --htmlhelp_basename = 'futuresdoc' -- -- --# -- Options for LaTeX output -------------------------------------------------- -- --# The paper size ('letter' or 'a4'). --#latex_paper_size = 'letter' -- --# The font size ('10pt', '11pt' or '12pt'). --#latex_font_size = '10pt' -- --# Grouping the document tree into LaTeX files. List of tuples --# (source start file, target name, title, author, documentclass [howto/manual]). --latex_documents = [ -- ('index', 'futures.tex', u'futures Documentation', -- u'Brian Quinlan', 'manual'), --] -- --# The name of an image file (relative to this directory) to place at the top of --# the title page. --#latex_logo = None -- --# For "manual" documents, if this is true, then toplevel headings are parts, --# not chapters. --#latex_use_parts = False -- --# Additional stuff for the LaTeX preamble. --#latex_preamble = '' -- --# Documents to append as an appendix to all manuals. --#latex_appendices = [] -- --# If false, no module index is generated. --#latex_use_modindex = True -diff --git a/third_party/pythonfutures/docs/index.rst b/third_party/pythonfutures/docs/index.rst -deleted file mode 100755 -index 525ce6ab3..000000000 ---- a/third_party/pythonfutures/docs/index.rst -+++ /dev/null -@@ -1,345 +0,0 @@ --:mod:`concurrent.futures` --- Asynchronous computation --====================================================== -- --.. module:: concurrent.futures -- :synopsis: Execute computations asynchronously using threads or processes. -- --The :mod:`concurrent.futures` module provides a high-level interface for --asynchronously executing callables. -- --The asynchronous execution can be be performed by threads using --:class:`ThreadPoolExecutor` or seperate processes using --:class:`ProcessPoolExecutor`. Both implement the same interface, which is --defined by the abstract :class:`Executor` class. -- --Executor Objects ------------------ -- --:class:`Executor` is an abstract class that provides methods to execute calls --asynchronously. It should not be used directly, but through its two --subclasses: :class:`ThreadPoolExecutor` and :class:`ProcessPoolExecutor`. -- --.. method:: Executor.submit(fn, *args, **kwargs) -- -- Schedules the callable to be executed as *fn*(*\*args*, *\*\*kwargs*) and -- returns a :class:`Future` representing the execution of the callable. -- --:: -- -- with ThreadPoolExecutor(max_workers=1) as executor: -- future = executor.submit(pow, 323, 1235) -- print(future.result()) -- --.. method:: Executor.map(func, *iterables, timeout=None) -- -- Equivalent to map(*func*, *\*iterables*) but func is executed asynchronously -- and several calls to *func* may be made concurrently. The returned iterator -- raises a :exc:`TimeoutError` if :meth:`__next__()` is called and the result -- isn't available after *timeout* seconds from the original call to -- :meth:`map()`. *timeout* can be an int or float. If *timeout* is not -- specified or ``None`` then there is no limit to the wait time. If a call -- raises an exception then that exception will be raised when its value is -- retrieved from the iterator. -- --.. method:: Executor.shutdown(wait=True) -- -- Signal the executor that it should free any resources that it is using when -- the currently pending futures are done executing. Calls to -- :meth:`Executor.submit` and :meth:`Executor.map` made after shutdown will -- raise :exc:`RuntimeError`. -- -- If *wait* is `True` then this method will not return until all the pending -- futures are done executing and the resources associated with the executor -- have been freed. If *wait* is `False` then this method will return -- immediately and the resources associated with the executor will be freed -- when all pending futures are done executing. Regardless of the value of -- *wait*, the entire Python program will not exit until all pending futures -- are done executing. -- -- You can avoid having to call this method explicitly if you use the `with` -- statement, which will shutdown the `Executor` (waiting as if -- `Executor.shutdown` were called with *wait* set to `True`): -- --:: -- -- import shutil -- with ThreadPoolExecutor(max_workers=4) as e: -- e.submit(shutil.copy, 'src1.txt', 'dest1.txt') -- e.submit(shutil.copy, 'src2.txt', 'dest2.txt') -- e.submit(shutil.copy, 'src3.txt', 'dest3.txt') -- e.submit(shutil.copy, 'src3.txt', 'dest4.txt') -- -- --ThreadPoolExecutor Objects ---------------------------- -- --The :class:`ThreadPoolExecutor` class is an :class:`Executor` subclass that uses --a pool of threads to execute calls asynchronously. -- --Deadlock can occur when the callable associated with a :class:`Future` waits on --the results of another :class:`Future`. For example: -- --:: -- -- import time -- def wait_on_b(): -- time.sleep(5) -- print(b.result()) # b will never complete because it is waiting on a. -- return 5 -- -- def wait_on_a(): -- time.sleep(5) -- print(a.result()) # a will never complete because it is waiting on b. -- return 6 -- -- -- executor = ThreadPoolExecutor(max_workers=2) -- a = executor.submit(wait_on_b) -- b = executor.submit(wait_on_a) -- --And: -- --:: -- -- def wait_on_future(): -- f = executor.submit(pow, 5, 2) -- # This will never complete because there is only one worker thread and -- # it is executing this function. -- print(f.result()) -- -- executor = ThreadPoolExecutor(max_workers=1) -- executor.submit(wait_on_future) -- --.. class:: ThreadPoolExecutor(max_workers) -- -- Executes calls asynchronously using at pool of at most *max_workers* threads. -- --.. _threadpoolexecutor-example: -- --ThreadPoolExecutor Example --^^^^^^^^^^^^^^^^^^^^^^^^^^ --:: -- -- from concurrent import futures -- import urllib.request -- -- URLS = ['http://www.foxnews.com/', -- 'http://www.cnn.com/', -- 'http://europe.wsj.com/', -- 'http://www.bbc.co.uk/', -- 'http://some-made-up-domain.com/'] -- -- def load_url(url, timeout): -- return urllib.request.urlopen(url, timeout=timeout).read() -- -- with futures.ThreadPoolExecutor(max_workers=5) as executor: -- future_to_url = dict((executor.submit(load_url, url, 60), url) -- for url in URLS) -- -- for future in futures.as_completed(future_to_url): -- url = future_to_url[future] -- if future.exception() is not None: -- print('%r generated an exception: %s' % (url, -- future.exception())) -- else: -- print('%r page is %d bytes' % (url, len(future.result()))) -- --ProcessPoolExecutor Objects ----------------------------- -- --The :class:`ProcessPoolExecutor` class is an :class:`Executor` subclass that --uses a pool of processes to execute calls asynchronously. --:class:`ProcessPoolExecutor` uses the :mod:`multiprocessing` module, which --allows it to side-step the :term:`Global Interpreter Lock` but also means that --only picklable objects can be executed and returned. -- --Calling :class:`Executor` or :class:`Future` methods from a callable submitted --to a :class:`ProcessPoolExecutor` will result in deadlock. -- --.. class:: ProcessPoolExecutor(max_workers=None) -- -- Executes calls asynchronously using a pool of at most *max_workers* -- processes. If *max_workers* is ``None`` or not given then as many worker -- processes will be created as the machine has processors. -- --.. _processpoolexecutor-example: -- --ProcessPoolExecutor Example --^^^^^^^^^^^^^^^^^^^^^^^^^^^ --:: -- -- import math -- -- PRIMES = [ -- 112272535095293, -- 112582705942171, -- 112272535095293, -- 115280095190773, -- 115797848077099, -- 1099726899285419] -- -- def is_prime(n): -- if n % 2 == 0: -- return False -- -- sqrt_n = int(math.floor(math.sqrt(n))) -- for i in range(3, sqrt_n + 1, 2): -- if n % i == 0: -- return False -- return True -- -- def main(): -- with futures.ProcessPoolExecutor() as executor: -- for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)): -- print('%d is prime: %s' % (number, prime)) -- -- if __name__ == '__main__': -- main() -- --Future Objects ---------------- -- --The :class:`Future` class encapulates the asynchronous execution of a callable. --:class:`Future` instances are created by :meth:`Executor.submit`. -- --.. method:: Future.cancel() -- -- Attempt to cancel the call. If the call is currently being executed then -- it cannot be cancelled and the method will return `False`, otherwise the call -- will be cancelled and the method will return `True`. -- --.. method:: Future.cancelled() -- -- Return `True` if the call was successfully cancelled. -- --.. method:: Future.running() -- -- Return `True` if the call is currently being executed and cannot be -- cancelled. -- --.. method:: Future.done() -- -- Return `True` if the call was successfully cancelled or finished running. -- --.. method:: Future.result(timeout=None) -- -- Return the value returned by the call. If the call hasn't yet completed then -- this method will wait up to *timeout* seconds. If the call hasn't completed -- in *timeout* seconds then a :exc:`TimeoutError` will be raised. *timeout* can -- be an int or float.If *timeout* is not specified or ``None`` then there is no -- limit to the wait time. -- -- If the future is cancelled before completing then :exc:`CancelledError` will -- be raised. -- -- If the call raised then this method will raise the same exception. -- --.. method:: Future.exception(timeout=None) -- -- Return the exception raised by the call. If the call hasn't yet completed -- then this method will wait up to *timeout* seconds. If the call hasn't -- completed in *timeout* seconds then a :exc:`TimeoutError` will be raised. -- *timeout* can be an int or float. If *timeout* is not specified or ``None`` -- then there is no limit to the wait time. -- -- If the future is cancelled before completing then :exc:`CancelledError` will -- be raised. -- -- If the call completed without raising then ``None`` is returned. -- --.. method:: Future.add_done_callback(fn) -- -- Attaches the callable *fn* to the future. *fn* will be called, with the -- future as its only argument, when the future is cancelled or finishes -- running. -- -- Added callables are called in the order that they were added and are always -- called in a thread belonging to the process that added them. If the callable -- raises an :exc:`Exception` then it will be logged and ignored. If the -- callable raises another :exc:`BaseException` then the behavior is not -- defined. -- -- If the future has already completed or been cancelled then *fn* will be -- called immediately. -- --Internal Future Methods --^^^^^^^^^^^^^^^^^^^^^^^ -- --The following :class:`Future` methods are meant for use in unit tests and --:class:`Executor` implementations. -- --.. method:: Future.set_running_or_notify_cancel() -- -- This method should only be called by :class:`Executor` implementations before -- executing the work associated with the :class:`Future` and by unit tests. -- -- If the method returns `False` then the :class:`Future` was cancelled i.e. -- :meth:`Future.cancel` was called and returned `True`. Any threads waiting -- on the :class:`Future` completing (i.e. through :func:`as_completed` or -- :func:`wait`) will be woken up. -- -- If the method returns `True` then the :class:`Future` was not cancelled -- and has been put in the running state i.e. calls to -- :meth:`Future.running` will return `True`. -- -- This method can only be called once and cannot be called after -- :meth:`Future.set_result` or :meth:`Future.set_exception` have been -- called. -- --.. method:: Future.set_result(result) -- -- Sets the result of the work associated with the :class:`Future` to *result*. -- -- This method should only be used by Executor implementations and unit tests. -- --.. method:: Future.set_exception(exception) -- -- Sets the result of the work associated with the :class:`Future` to the -- :class:`Exception` *exception*. -- -- This method should only be used by Executor implementations and unit tests. -- --Module Functions ------------------ -- --.. function:: wait(fs, timeout=None, return_when=ALL_COMPLETED) -- -- Wait for the :class:`Future` instances (possibly created by different -- :class:`Executor` instances) given by *fs* to complete. Returns a named -- 2-tuple of sets. The first set, named "done", contains the futures that -- completed (finished or were cancelled) before the wait completed. The second -- set, named "not_done", contains uncompleted futures. -- -- *timeout* can be used to control the maximum number of seconds to wait before -- returning. *timeout* can be an int or float. If *timeout* is not specified or -- ``None`` then there is no limit to the wait time. -- -- *return_when* indicates when this function should return. It must be one of -- the following constants: -- -- +-----------------------------+----------------------------------------+ -- | Constant | Description | -- +=============================+========================================+ -- | :const:`FIRST_COMPLETED` | The function will return when any | -- | | future finishes or is cancelled. | -- +-----------------------------+----------------------------------------+ -- | :const:`FIRST_EXCEPTION` | The function will return when any | -- | | future finishes by raising an | -- | | exception. If no future raises an | -- | | exception then it is equivalent to | -- | | `ALL_COMPLETED`. | -- +-----------------------------+----------------------------------------+ -- | :const:`ALL_COMPLETED` | The function will return when all | -- | | futures finish or are cancelled. | -- +-----------------------------+----------------------------------------+ -- --.. function:: as_completed(fs, timeout=None) -- -- Returns an iterator over the :class:`Future` instances (possibly created -- by different :class:`Executor` instances) given by *fs* that yields futures -- as they complete (finished or were cancelled). Any futures that completed -- before :func:`as_completed()` was called will be yielded first. The returned -- iterator raises a :exc:`TimeoutError` if :meth:`__next__()` is called and -- the result isn't available after *timeout* seconds from the original call -- to :func:`as_completed()`. *timeout* can be an int or float. If *timeout* -- is not specified or ``None`` then there is no limit to the wait time. -diff --git a/third_party/pythonfutures/docs/make.bat b/third_party/pythonfutures/docs/make.bat -deleted file mode 100755 -index 3e8021b56..000000000 ---- a/third_party/pythonfutures/docs/make.bat -+++ /dev/null -@@ -1,112 +0,0 @@ --@ECHO OFF -- --REM Command file for Sphinx documentation -- --set SPHINXBUILD=sphinx-build --set ALLSPHINXOPTS=-d _build/doctrees %SPHINXOPTS% . --if NOT "%PAPER%" == "" ( -- set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% --) -- --if "%1" == "" goto help -- --if "%1" == "help" ( -- :help -- echo.Please use `make ^` where ^ is one of -- echo. html to make standalone HTML files -- echo. dirhtml to make HTML files named index.html in directories -- echo. pickle to make pickle files -- echo. json to make JSON files -- echo. htmlhelp to make HTML files and a HTML help project -- echo. qthelp to make HTML files and a qthelp project -- echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter -- echo. changes to make an overview over all changed/added/deprecated items -- echo. linkcheck to check all external links for integrity -- echo. doctest to run all doctests embedded in the documentation if enabled -- goto end --) -- --if "%1" == "clean" ( -- for /d %%i in (_build\*) do rmdir /q /s %%i -- del /q /s _build\* -- goto end --) -- --if "%1" == "html" ( -- %SPHINXBUILD% -b html %ALLSPHINXOPTS% _build/html -- echo. -- echo.Build finished. The HTML pages are in _build/html. -- goto end --) -- --if "%1" == "dirhtml" ( -- %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% _build/dirhtml -- echo. -- echo.Build finished. The HTML pages are in _build/dirhtml. -- goto end --) -- --if "%1" == "pickle" ( -- %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% _build/pickle -- echo. -- echo.Build finished; now you can process the pickle files. -- goto end --) -- --if "%1" == "json" ( -- %SPHINXBUILD% -b json %ALLSPHINXOPTS% _build/json -- echo. -- echo.Build finished; now you can process the JSON files. -- goto end --) -- --if "%1" == "htmlhelp" ( -- %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% _build/htmlhelp -- echo. -- echo.Build finished; now you can run HTML Help Workshop with the ^ --.hhp project file in _build/htmlhelp. -- goto end --) -- --if "%1" == "qthelp" ( -- %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% _build/qthelp -- echo. -- echo.Build finished; now you can run "qcollectiongenerator" with the ^ --.qhcp project file in _build/qthelp, like this: -- echo.^> qcollectiongenerator _build\qthelp\futures.qhcp -- echo.To view the help file: -- echo.^> assistant -collectionFile _build\qthelp\futures.ghc -- goto end --) -- --if "%1" == "latex" ( -- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% _build/latex -- echo. -- echo.Build finished; the LaTeX files are in _build/latex. -- goto end --) -- --if "%1" == "changes" ( -- %SPHINXBUILD% -b changes %ALLSPHINXOPTS% _build/changes -- echo. -- echo.The overview file is in _build/changes. -- goto end --) -- --if "%1" == "linkcheck" ( -- %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% _build/linkcheck -- echo. -- echo.Link check complete; look for any errors in the above output ^ --or in _build/linkcheck/output.txt. -- goto end --) -- --if "%1" == "doctest" ( -- %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% _build/doctest -- echo. -- echo.Testing of doctests in the sources finished, look at the ^ --results in _build/doctest/output.txt. -- goto end --) -- --:end -diff --git a/third_party/pythonfutures/futures/__init__.py b/third_party/pythonfutures/futures/__init__.py -deleted file mode 100755 -index 8f8b23481..000000000 ---- a/third_party/pythonfutures/futures/__init__.py -+++ /dev/null -@@ -1,24 +0,0 @@ --# Copyright 2009 Brian Quinlan. All Rights Reserved. --# Licensed to PSF under a Contributor Agreement. -- --"""Execute computations asynchronously using threads or processes.""" -- --import warnings -- --from concurrent.futures import (FIRST_COMPLETED, -- FIRST_EXCEPTION, -- ALL_COMPLETED, -- CancelledError, -- TimeoutError, -- Future, -- Executor, -- wait, -- as_completed, -- ProcessPoolExecutor, -- ThreadPoolExecutor) -- --__author__ = 'Brian Quinlan (brian@sweetapp.com)' -- --warnings.warn('The futures package has been deprecated. ' -- 'Use the concurrent.futures package instead.', -- DeprecationWarning) -diff --git a/third_party/pythonfutures/futures/process.py b/third_party/pythonfutures/futures/process.py -deleted file mode 100755 -index e9d37b16c..000000000 ---- a/third_party/pythonfutures/futures/process.py -+++ /dev/null -@@ -1 +0,0 @@ --from concurrent.futures import ProcessPoolExecutor -diff --git a/third_party/pythonfutures/futures/thread.py b/third_party/pythonfutures/futures/thread.py -deleted file mode 100755 -index f6bd05de6..000000000 ---- a/third_party/pythonfutures/futures/thread.py -+++ /dev/null -@@ -1 +0,0 @@ --from concurrent.futures import ThreadPoolExecutor -diff --git a/third_party/pythonfutures/primes.py b/third_party/pythonfutures/primes.py -deleted file mode 100755 -index 0da2b3e64..000000000 ---- a/third_party/pythonfutures/primes.py -+++ /dev/null -@@ -1,50 +0,0 @@ --from __future__ import with_statement --import math --import time --import sys -- --from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor -- --PRIMES = [ -- 112272535095293, -- 112582705942171, -- 112272535095293, -- 115280095190773, -- 115797848077099, -- 117450548693743, -- 993960000099397] -- --def is_prime(n): -- if n % 2 == 0: -- return False -- -- sqrt_n = int(math.floor(math.sqrt(n))) -- for i in range(3, sqrt_n + 1, 2): -- if n % i == 0: -- return False -- return True -- --def sequential(): -- return list(map(is_prime, PRIMES)) -- --def with_process_pool_executor(): -- with ProcessPoolExecutor(10) as executor: -- return list(executor.map(is_prime, PRIMES)) -- --def with_thread_pool_executor(): -- with ThreadPoolExecutor(10) as executor: -- return list(executor.map(is_prime, PRIMES)) -- --def main(): -- for name, fn in [('sequential', sequential), -- ('processes', with_process_pool_executor), -- ('threads', with_thread_pool_executor)]: -- sys.stdout.write('%s: ' % name.ljust(12)) -- start = time.time() -- if fn() != [True] * len(PRIMES): -- sys.stdout.write('failed\n') -- else: -- sys.stdout.write('%.2f seconds\n' % (time.time() - start)) -- --if __name__ == '__main__': -- main() -diff --git a/third_party/pythonfutures/setup.cfg b/third_party/pythonfutures/setup.cfg -deleted file mode 100755 -index 0a9f4f521..000000000 ---- a/third_party/pythonfutures/setup.cfg -+++ /dev/null -@@ -1,6 +0,0 @@ --[build_sphinx] --source-dir = docs --build-dir = build/sphinx -- --[upload_docs] --upload-dir = build/sphinx/html -diff --git a/third_party/pythonfutures/setup.py b/third_party/pythonfutures/setup.py -deleted file mode 100755 -index c08461eda..000000000 ---- a/third_party/pythonfutures/setup.py -+++ /dev/null -@@ -1,33 +0,0 @@ --#!/usr/bin/env python --import sys -- --extras = {} --try: -- from setuptools import setup -- extras['zip_safe'] = False -- if sys.version_info < (2, 6): -- extras['install_requires'] = ['multiprocessing'] --except ImportError: -- from distutils.core import setup -- --setup(name='futures', -- version='2.1.4', -- description='Backport of the concurrent.futures package from Python 3.2', -- author='Brian Quinlan', -- author_email='brian@sweetapp.com', -- maintainer='Alex Gronholm', -- maintainer_email='alex.gronholm+pypi@nextday.fi', -- url='http://code.google.com/p/pythonfutures', -- download_url='http://pypi.python.org/pypi/futures/', -- packages=['futures', 'concurrent', 'concurrent.futures'], -- license='BSD', -- classifiers=['License :: OSI Approved :: BSD License', -- 'Development Status :: 5 - Production/Stable', -- 'Intended Audience :: Developers', -- 'Programming Language :: Python :: 2.5', -- 'Programming Language :: Python :: 2.6', -- 'Programming Language :: Python :: 2.7', -- 'Programming Language :: Python :: 3', -- 'Programming Language :: Python :: 3.1'], -- **extras -- ) -diff --git a/third_party/pythonfutures/test_futures.py b/third_party/pythonfutures/test_futures.py -deleted file mode 100755 -index dd7fd3e69..000000000 ---- a/third_party/pythonfutures/test_futures.py -+++ /dev/null -@@ -1,723 +0,0 @@ --from __future__ import with_statement --import os --import subprocess --import sys --import threading --import functools --import contextlib --import logging --import re --import time -- --from concurrent import futures --from concurrent.futures._base import ( -- PENDING, RUNNING, CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED, Future) -- --try: -- import unittest2 as unittest --except ImportError: -- import unittest -- --try: -- from StringIO import StringIO --except ImportError: -- from io import StringIO -- --try: -- from test import test_support --except ImportError: -- from test import support as test_support -- --try: -- next --except NameError: -- next = lambda x: x.next() -- -- --def reap_threads(func): -- """Use this function when threads are being used. This will -- ensure that the threads are cleaned up even when the test fails. -- If threading is unavailable this function does nothing. -- """ -- @functools.wraps(func) -- def decorator(*args): -- key = test_support.threading_setup() -- try: -- return func(*args) -- finally: -- test_support.threading_cleanup(*key) -- return decorator -- -- --# Executing the interpreter in a subprocess --def _assert_python(expected_success, *args, **env_vars): -- cmd_line = [sys.executable] -- if not env_vars: -- cmd_line.append('-E') -- # Need to preserve the original environment, for in-place testing of -- # shared library builds. -- env = os.environ.copy() -- # But a special flag that can be set to override -- in this case, the -- # caller is responsible to pass the full environment. -- if env_vars.pop('__cleanenv', None): -- env = {} -- env.update(env_vars) -- cmd_line.extend(args) -- p = subprocess.Popen(cmd_line, stdin=subprocess.PIPE, -- stdout=subprocess.PIPE, stderr=subprocess.PIPE, -- env=env) -- try: -- out, err = p.communicate() -- finally: -- subprocess._cleanup() -- p.stdout.close() -- p.stderr.close() -- rc = p.returncode -- err = strip_python_stderr(err) -- if (rc and expected_success) or (not rc and not expected_success): -- raise AssertionError( -- "Process return code is %d, " -- "stderr follows:\n%s" % (rc, err.decode('ascii', 'ignore'))) -- return rc, out, err -- -- --def assert_python_ok(*args, **env_vars): -- """ -- Assert that running the interpreter with `args` and optional environment -- variables `env_vars` is ok and return a (return code, stdout, stderr) tuple. -- """ -- return _assert_python(True, *args, **env_vars) -- -- --def strip_python_stderr(stderr): -- """Strip the stderr of a Python process from potential debug output -- emitted by the interpreter. -- -- This will typically be run on the result of the communicate() method -- of a subprocess.Popen object. -- """ -- stderr = re.sub(r"\[\d+ refs\]\r?\n?$".encode(), "".encode(), stderr).strip() -- return stderr -- -- --@contextlib.contextmanager --def captured_stderr(): -- """Return a context manager used by captured_stdout/stdin/stderr -- that temporarily replaces the sys stream *stream_name* with a StringIO.""" -- logging_stream = StringIO() -- handler = logging.StreamHandler(logging_stream) -- logging.root.addHandler(handler) -- -- try: -- yield logging_stream -- finally: -- logging.root.removeHandler(handler) -- -- --def create_future(state=PENDING, exception=None, result=None): -- f = Future() -- f._state = state -- f._exception = exception -- f._result = result -- return f -- -- --PENDING_FUTURE = create_future(state=PENDING) --RUNNING_FUTURE = create_future(state=RUNNING) --CANCELLED_FUTURE = create_future(state=CANCELLED) --CANCELLED_AND_NOTIFIED_FUTURE = create_future(state=CANCELLED_AND_NOTIFIED) --EXCEPTION_FUTURE = create_future(state=FINISHED, exception=IOError()) --SUCCESSFUL_FUTURE = create_future(state=FINISHED, result=42) -- -- --def mul(x, y): -- return x * y -- -- --def sleep_and_raise(t): -- time.sleep(t) -- raise Exception('this is an exception') -- --def sleep_and_print(t, msg): -- time.sleep(t) -- print(msg) -- sys.stdout.flush() -- -- --class ExecutorMixin: -- worker_count = 5 -- -- def setUp(self): -- self.t1 = time.time() -- try: -- self.executor = self.executor_type(max_workers=self.worker_count) -- except NotImplementedError: -- e = sys.exc_info()[1] -- self.skipTest(str(e)) -- self._prime_executor() -- -- def tearDown(self): -- self.executor.shutdown(wait=True) -- dt = time.time() - self.t1 -- if test_support.verbose: -- print("%.2fs" % dt) -- self.assertLess(dt, 60, "synchronization issue: test lasted too long") -- -- def _prime_executor(self): -- # Make sure that the executor is ready to do work before running the -- # tests. This should reduce the probability of timeouts in the tests. -- futures = [self.executor.submit(time.sleep, 0.1) -- for _ in range(self.worker_count)] -- -- for f in futures: -- f.result() -- -- --class ThreadPoolMixin(ExecutorMixin): -- executor_type = futures.ThreadPoolExecutor -- -- --class ProcessPoolMixin(ExecutorMixin): -- executor_type = futures.ProcessPoolExecutor -- -- --class ExecutorShutdownTest(unittest.TestCase): -- def test_run_after_shutdown(self): -- self.executor.shutdown() -- self.assertRaises(RuntimeError, -- self.executor.submit, -- pow, 2, 5) -- -- def test_interpreter_shutdown(self): -- # Test the atexit hook for shutdown of worker threads and processes -- rc, out, err = assert_python_ok('-c', """if 1: -- from concurrent.futures import %s -- from time import sleep -- from test_futures import sleep_and_print -- t = %s(5) -- t.submit(sleep_and_print, 1.0, "apple") -- """ % (self.executor_type.__name__, self.executor_type.__name__)) -- # Errors in atexit hooks don't change the process exit code, check -- # stderr manually. -- self.assertFalse(err) -- self.assertEqual(out.strip(), "apple".encode()) -- -- def test_hang_issue12364(self): -- fs = [self.executor.submit(time.sleep, 0.1) for _ in range(50)] -- self.executor.shutdown() -- for f in fs: -- f.result() -- -- --class ThreadPoolShutdownTest(ThreadPoolMixin, ExecutorShutdownTest): -- def _prime_executor(self): -- pass -- -- def test_threads_terminate(self): -- self.executor.submit(mul, 21, 2) -- self.executor.submit(mul, 6, 7) -- self.executor.submit(mul, 3, 14) -- self.assertEqual(len(self.executor._threads), 3) -- self.executor.shutdown() -- for t in self.executor._threads: -- t.join() -- -- def test_context_manager_shutdown(self): -- with futures.ThreadPoolExecutor(max_workers=5) as e: -- executor = e -- self.assertEqual(list(e.map(abs, range(-5, 5))), -- [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) -- -- for t in executor._threads: -- t.join() -- -- def test_del_shutdown(self): -- executor = futures.ThreadPoolExecutor(max_workers=5) -- executor.map(abs, range(-5, 5)) -- threads = executor._threads -- del executor -- -- for t in threads: -- t.join() -- -- --class ProcessPoolShutdownTest(ProcessPoolMixin, ExecutorShutdownTest): -- def _prime_executor(self): -- pass -- -- def test_processes_terminate(self): -- self.executor.submit(mul, 21, 2) -- self.executor.submit(mul, 6, 7) -- self.executor.submit(mul, 3, 14) -- self.assertEqual(len(self.executor._processes), 5) -- processes = self.executor._processes -- self.executor.shutdown() -- -- for p in processes: -- p.join() -- -- def test_context_manager_shutdown(self): -- with futures.ProcessPoolExecutor(max_workers=5) as e: -- processes = e._processes -- self.assertEqual(list(e.map(abs, range(-5, 5))), -- [5, 4, 3, 2, 1, 0, 1, 2, 3, 4]) -- -- for p in processes: -- p.join() -- -- def test_del_shutdown(self): -- executor = futures.ProcessPoolExecutor(max_workers=5) -- list(executor.map(abs, range(-5, 5))) -- queue_management_thread = executor._queue_management_thread -- processes = executor._processes -- del executor -- -- queue_management_thread.join() -- for p in processes: -- p.join() -- -- --class WaitTests(unittest.TestCase): -- -- def test_first_completed(self): -- future1 = self.executor.submit(mul, 21, 2) -- future2 = self.executor.submit(time.sleep, 1.5) -- -- done, not_done = futures.wait( -- [CANCELLED_FUTURE, future1, future2], -- return_when=futures.FIRST_COMPLETED) -- -- self.assertEqual(set([future1]), done) -- self.assertEqual(set([CANCELLED_FUTURE, future2]), not_done) -- -- def test_first_completed_some_already_completed(self): -- future1 = self.executor.submit(time.sleep, 1.5) -- -- finished, pending = futures.wait( -- [CANCELLED_AND_NOTIFIED_FUTURE, SUCCESSFUL_FUTURE, future1], -- return_when=futures.FIRST_COMPLETED) -- -- self.assertEqual( -- set([CANCELLED_AND_NOTIFIED_FUTURE, SUCCESSFUL_FUTURE]), -- finished) -- self.assertEqual(set([future1]), pending) -- -- def test_first_exception(self): -- future1 = self.executor.submit(mul, 2, 21) -- future2 = self.executor.submit(sleep_and_raise, 1.5) -- future3 = self.executor.submit(time.sleep, 3) -- -- finished, pending = futures.wait( -- [future1, future2, future3], -- return_when=futures.FIRST_EXCEPTION) -- -- self.assertEqual(set([future1, future2]), finished) -- self.assertEqual(set([future3]), pending) -- -- def test_first_exception_some_already_complete(self): -- future1 = self.executor.submit(divmod, 21, 0) -- future2 = self.executor.submit(time.sleep, 1.5) -- -- finished, pending = futures.wait( -- [SUCCESSFUL_FUTURE, -- CANCELLED_FUTURE, -- CANCELLED_AND_NOTIFIED_FUTURE, -- future1, future2], -- return_when=futures.FIRST_EXCEPTION) -- -- self.assertEqual(set([SUCCESSFUL_FUTURE, -- CANCELLED_AND_NOTIFIED_FUTURE, -- future1]), finished) -- self.assertEqual(set([CANCELLED_FUTURE, future2]), pending) -- -- def test_first_exception_one_already_failed(self): -- future1 = self.executor.submit(time.sleep, 2) -- -- finished, pending = futures.wait( -- [EXCEPTION_FUTURE, future1], -- return_when=futures.FIRST_EXCEPTION) -- -- self.assertEqual(set([EXCEPTION_FUTURE]), finished) -- self.assertEqual(set([future1]), pending) -- -- def test_all_completed(self): -- future1 = self.executor.submit(divmod, 2, 0) -- future2 = self.executor.submit(mul, 2, 21) -- -- finished, pending = futures.wait( -- [SUCCESSFUL_FUTURE, -- CANCELLED_AND_NOTIFIED_FUTURE, -- EXCEPTION_FUTURE, -- future1, -- future2], -- return_when=futures.ALL_COMPLETED) -- -- self.assertEqual(set([SUCCESSFUL_FUTURE, -- CANCELLED_AND_NOTIFIED_FUTURE, -- EXCEPTION_FUTURE, -- future1, -- future2]), finished) -- self.assertEqual(set(), pending) -- -- def test_timeout(self): -- future1 = self.executor.submit(mul, 6, 7) -- future2 = self.executor.submit(time.sleep, 3) -- -- finished, pending = futures.wait( -- [CANCELLED_AND_NOTIFIED_FUTURE, -- EXCEPTION_FUTURE, -- SUCCESSFUL_FUTURE, -- future1, future2], -- timeout=1.5, -- return_when=futures.ALL_COMPLETED) -- -- self.assertEqual(set([CANCELLED_AND_NOTIFIED_FUTURE, -- EXCEPTION_FUTURE, -- SUCCESSFUL_FUTURE, -- future1]), finished) -- self.assertEqual(set([future2]), pending) -- -- --class ThreadPoolWaitTests(ThreadPoolMixin, WaitTests): -- -- def test_pending_calls_race(self): -- # Issue #14406: multi-threaded race condition when waiting on all -- # futures. -- event = threading.Event() -- def future_func(): -- event.wait() -- oldswitchinterval = sys.getcheckinterval() -- sys.setcheckinterval(1) -- try: -- fs = set(self.executor.submit(future_func) for i in range(100)) -- event.set() -- futures.wait(fs, return_when=futures.ALL_COMPLETED) -- finally: -- sys.setcheckinterval(oldswitchinterval) -- -- --class ProcessPoolWaitTests(ProcessPoolMixin, WaitTests): -- pass -- -- --class AsCompletedTests(unittest.TestCase): -- # TODO(brian@sweetapp.com): Should have a test with a non-zero timeout. -- def test_no_timeout(self): -- future1 = self.executor.submit(mul, 2, 21) -- future2 = self.executor.submit(mul, 7, 6) -- -- completed = set(futures.as_completed( -- [CANCELLED_AND_NOTIFIED_FUTURE, -- EXCEPTION_FUTURE, -- SUCCESSFUL_FUTURE, -- future1, future2])) -- self.assertEqual(set( -- [CANCELLED_AND_NOTIFIED_FUTURE, -- EXCEPTION_FUTURE, -- SUCCESSFUL_FUTURE, -- future1, future2]), -- completed) -- -- def test_zero_timeout(self): -- future1 = self.executor.submit(time.sleep, 2) -- completed_futures = set() -- try: -- for future in futures.as_completed( -- [CANCELLED_AND_NOTIFIED_FUTURE, -- EXCEPTION_FUTURE, -- SUCCESSFUL_FUTURE, -- future1], -- timeout=0): -- completed_futures.add(future) -- except futures.TimeoutError: -- pass -- -- self.assertEqual(set([CANCELLED_AND_NOTIFIED_FUTURE, -- EXCEPTION_FUTURE, -- SUCCESSFUL_FUTURE]), -- completed_futures) -- -- --class ThreadPoolAsCompletedTests(ThreadPoolMixin, AsCompletedTests): -- pass -- -- --class ProcessPoolAsCompletedTests(ProcessPoolMixin, AsCompletedTests): -- pass -- -- --class ExecutorTest(unittest.TestCase): -- # Executor.shutdown() and context manager usage is tested by -- # ExecutorShutdownTest. -- def test_submit(self): -- future = self.executor.submit(pow, 2, 8) -- self.assertEqual(256, future.result()) -- -- def test_submit_keyword(self): -- future = self.executor.submit(mul, 2, y=8) -- self.assertEqual(16, future.result()) -- -- def test_map(self): -- self.assertEqual( -- list(self.executor.map(pow, range(10), range(10))), -- list(map(pow, range(10), range(10)))) -- -- def test_map_exception(self): -- i = self.executor.map(divmod, [1, 1, 1, 1], [2, 3, 0, 5]) -- self.assertEqual(next(i), (0, 1)) -- self.assertEqual(next(i), (0, 1)) -- self.assertRaises(ZeroDivisionError, next, i) -- -- def test_map_timeout(self): -- results = [] -- try: -- for i in self.executor.map(time.sleep, -- [0, 0, 3], -- timeout=1.5): -- results.append(i) -- except futures.TimeoutError: -- pass -- else: -- self.fail('expected TimeoutError') -- -- self.assertEqual([None, None], results) -- -- --class ThreadPoolExecutorTest(ThreadPoolMixin, ExecutorTest): -- pass -- -- --class ProcessPoolExecutorTest(ProcessPoolMixin, ExecutorTest): -- pass -- -- --class FutureTests(unittest.TestCase): -- def test_done_callback_with_result(self): -- callback_result = [None] -- def fn(callback_future): -- callback_result[0] = callback_future.result() -- -- f = Future() -- f.add_done_callback(fn) -- f.set_result(5) -- self.assertEqual(5, callback_result[0]) -- -- def test_done_callback_with_exception(self): -- callback_exception = [None] -- def fn(callback_future): -- callback_exception[0] = callback_future.exception() -- -- f = Future() -- f.add_done_callback(fn) -- f.set_exception(Exception('test')) -- self.assertEqual(('test',), callback_exception[0].args) -- -- def test_done_callback_with_cancel(self): -- was_cancelled = [None] -- def fn(callback_future): -- was_cancelled[0] = callback_future.cancelled() -- -- f = Future() -- f.add_done_callback(fn) -- self.assertTrue(f.cancel()) -- self.assertTrue(was_cancelled[0]) -- -- def test_done_callback_raises(self): -- with captured_stderr() as stderr: -- raising_was_called = [False] -- fn_was_called = [False] -- -- def raising_fn(callback_future): -- raising_was_called[0] = True -- raise Exception('doh!') -- -- def fn(callback_future): -- fn_was_called[0] = True -- -- f = Future() -- f.add_done_callback(raising_fn) -- f.add_done_callback(fn) -- f.set_result(5) -- self.assertTrue(raising_was_called) -- self.assertTrue(fn_was_called) -- self.assertIn('Exception: doh!', stderr.getvalue()) -- -- def test_done_callback_already_successful(self): -- callback_result = [None] -- def fn(callback_future): -- callback_result[0] = callback_future.result() -- -- f = Future() -- f.set_result(5) -- f.add_done_callback(fn) -- self.assertEqual(5, callback_result[0]) -- -- def test_done_callback_already_failed(self): -- callback_exception = [None] -- def fn(callback_future): -- callback_exception[0] = callback_future.exception() -- -- f = Future() -- f.set_exception(Exception('test')) -- f.add_done_callback(fn) -- self.assertEqual(('test',), callback_exception[0].args) -- -- def test_done_callback_already_cancelled(self): -- was_cancelled = [None] -- def fn(callback_future): -- was_cancelled[0] = callback_future.cancelled() -- -- f = Future() -- self.assertTrue(f.cancel()) -- f.add_done_callback(fn) -- self.assertTrue(was_cancelled[0]) -- -- def test_repr(self): -- self.assertRegexpMatches(repr(PENDING_FUTURE), -- '') -- self.assertRegexpMatches(repr(RUNNING_FUTURE), -- '') -- self.assertRegexpMatches(repr(CANCELLED_FUTURE), -- '') -- self.assertRegexpMatches(repr(CANCELLED_AND_NOTIFIED_FUTURE), -- '') -- self.assertRegexpMatches( -- repr(EXCEPTION_FUTURE), -- '') -- self.assertRegexpMatches( -- repr(SUCCESSFUL_FUTURE), -- '') -- -- def test_cancel(self): -- f1 = create_future(state=PENDING) -- f2 = create_future(state=RUNNING) -- f3 = create_future(state=CANCELLED) -- f4 = create_future(state=CANCELLED_AND_NOTIFIED) -- f5 = create_future(state=FINISHED, exception=IOError()) -- f6 = create_future(state=FINISHED, result=5) -- -- self.assertTrue(f1.cancel()) -- self.assertEqual(f1._state, CANCELLED) -- -- self.assertFalse(f2.cancel()) -- self.assertEqual(f2._state, RUNNING) -- -- self.assertTrue(f3.cancel()) -- self.assertEqual(f3._state, CANCELLED) -- -- self.assertTrue(f4.cancel()) -- self.assertEqual(f4._state, CANCELLED_AND_NOTIFIED) -- -- self.assertFalse(f5.cancel()) -- self.assertEqual(f5._state, FINISHED) -- -- self.assertFalse(f6.cancel()) -- self.assertEqual(f6._state, FINISHED) -- -- def test_cancelled(self): -- self.assertFalse(PENDING_FUTURE.cancelled()) -- self.assertFalse(RUNNING_FUTURE.cancelled()) -- self.assertTrue(CANCELLED_FUTURE.cancelled()) -- self.assertTrue(CANCELLED_AND_NOTIFIED_FUTURE.cancelled()) -- self.assertFalse(EXCEPTION_FUTURE.cancelled()) -- self.assertFalse(SUCCESSFUL_FUTURE.cancelled()) -- -- def test_done(self): -- self.assertFalse(PENDING_FUTURE.done()) -- self.assertFalse(RUNNING_FUTURE.done()) -- self.assertTrue(CANCELLED_FUTURE.done()) -- self.assertTrue(CANCELLED_AND_NOTIFIED_FUTURE.done()) -- self.assertTrue(EXCEPTION_FUTURE.done()) -- self.assertTrue(SUCCESSFUL_FUTURE.done()) -- -- def test_running(self): -- self.assertFalse(PENDING_FUTURE.running()) -- self.assertTrue(RUNNING_FUTURE.running()) -- self.assertFalse(CANCELLED_FUTURE.running()) -- self.assertFalse(CANCELLED_AND_NOTIFIED_FUTURE.running()) -- self.assertFalse(EXCEPTION_FUTURE.running()) -- self.assertFalse(SUCCESSFUL_FUTURE.running()) -- -- def test_result_with_timeout(self): -- self.assertRaises(futures.TimeoutError, -- PENDING_FUTURE.result, timeout=0) -- self.assertRaises(futures.TimeoutError, -- RUNNING_FUTURE.result, timeout=0) -- self.assertRaises(futures.CancelledError, -- CANCELLED_FUTURE.result, timeout=0) -- self.assertRaises(futures.CancelledError, -- CANCELLED_AND_NOTIFIED_FUTURE.result, timeout=0) -- self.assertRaises(IOError, EXCEPTION_FUTURE.result, timeout=0) -- self.assertEqual(SUCCESSFUL_FUTURE.result(timeout=0), 42) -- -- def test_result_with_success(self): -- # TODO(brian@sweetapp.com): This test is timing dependant. -- def notification(): -- # Wait until the main thread is waiting for the result. -- time.sleep(1) -- f1.set_result(42) -- -- f1 = create_future(state=PENDING) -- t = threading.Thread(target=notification) -- t.start() -- -- self.assertEqual(f1.result(timeout=5), 42) -- -- def test_result_with_cancel(self): -- # TODO(brian@sweetapp.com): This test is timing dependant. -- def notification(): -- # Wait until the main thread is waiting for the result. -- time.sleep(1) -- f1.cancel() -- -- f1 = create_future(state=PENDING) -- t = threading.Thread(target=notification) -- t.start() -- -- self.assertRaises(futures.CancelledError, f1.result, timeout=5) -- -- def test_exception_with_timeout(self): -- self.assertRaises(futures.TimeoutError, -- PENDING_FUTURE.exception, timeout=0) -- self.assertRaises(futures.TimeoutError, -- RUNNING_FUTURE.exception, timeout=0) -- self.assertRaises(futures.CancelledError, -- CANCELLED_FUTURE.exception, timeout=0) -- self.assertRaises(futures.CancelledError, -- CANCELLED_AND_NOTIFIED_FUTURE.exception, timeout=0) -- self.assertTrue(isinstance(EXCEPTION_FUTURE.exception(timeout=0), -- IOError)) -- self.assertEqual(SUCCESSFUL_FUTURE.exception(timeout=0), None) -- -- def test_exception_with_success(self): -- def notification(): -- # Wait until the main thread is waiting for the exception. -- time.sleep(1) -- with f1._condition: -- f1._state = FINISHED -- f1._exception = IOError() -- f1._condition.notify_all() -- -- f1 = create_future(state=PENDING) -- t = threading.Thread(target=notification) -- t.start() -- -- self.assertTrue(isinstance(f1.exception(timeout=5), IOError)) -- --@reap_threads --def test_main(): -- try: -- test_support.run_unittest(ProcessPoolExecutorTest, -- ThreadPoolExecutorTest, -- ProcessPoolWaitTests, -- ThreadPoolWaitTests, -- ProcessPoolAsCompletedTests, -- ThreadPoolAsCompletedTests, -- FutureTests, -- ProcessPoolShutdownTest, -- ThreadPoolShutdownTest) -- finally: -- test_support.reap_children() -- --if __name__ == "__main__": -- test_main() -diff --git a/third_party/pythonfutures/tox.ini b/third_party/pythonfutures/tox.ini -deleted file mode 100755 -index c1ff2f13f..000000000 ---- a/third_party/pythonfutures/tox.ini -+++ /dev/null -@@ -1,8 +0,0 @@ --[tox] --envlist = py26,py27,py31 -- --[testenv] --commands={envpython} test_futures.py [] -- --[testenv:py26] --deps=unittest2 diff --git a/app-vim/youcompleteme/youcompleteme-20200203-r5.ebuild b/app-vim/youcompleteme/youcompleteme-20200203-r5.ebuild deleted file mode 100644 index edbac54..0000000 --- a/app-vim/youcompleteme/youcompleteme-20200203-r5.ebuild +++ /dev/null @@ -1,118 +0,0 @@ -EAPI="7" -PYTHON_COMPAT=( python3_{4,5,6,7,8,9,10} ) -inherit multilib python-single-r1 cmake-utils vim-plugin - -youcompletemev="124661f218e80b96c1f9f3d124e99f9a2fd2d83b" -ycmdv="d3378ca3a3103535c14b104cb916dcbcdaf93eeb" -reqfuv="148451a06781d8196e5fb7e0e2bca7a765368ff1" -ossv="e1902915c6790bcec00b8d551199c8a3537d33c9" -gocodev="5bee97b488366fd20b054d0861b89834ff5bbfb2" - -KEYWORDS="~amd64 ~x86" -SRC_URI=" - https://github.com/Valloric/YouCompleteMe/archive/$youcompletemev.tar.gz -> youcompleteme-$youcompletemev.tar.gz - https://github.com/Valloric/ycmd/archive/$ycmdv.tar.gz -> ycmd-$ycmdv.tar.gz - https://github.com/ross/requests-futures/archive/$reqfuv.tar.gz -> requests-futures-$reqfuv.tar.gz - csharp? ( https://github.com/OmniSharp/omnisharp-server/archive/$ossv.tar.gz -> omnisharp-server-$ossv.tar.gz ) - go? ( https://github.com/nsf/gocode/archive/$gocodev.tar.gz -> gocode-$gocodev.tar.gz ) -" - -DESCRIPTION="vim plugin: a code-completion engine for Vim" -HOMEPAGE="http://valloric.github.io/YouCompleteMe/" - -LICENSE="GPL-3" -IUSE="+clang test go csharp" -#REQUIRED_USE="${PYTHON_REQUIRED_USE}" - -COMMON_DEPEND=" - ${PYTHON_DEPS} - clang? ( sys-devel/clang ) - $(python_gen_cond_dep ' - >=dev-libs/boost-1.65:=[python,threads,${PYTHON_MULTI_USEDEP}] - || ( - app-editors/vim[python,${PYTHON_SINGLE_USEDEP}] - app-editors/gvim[python,${PYTHON_SINGLE_USEDEP}] - ) - ') -" -RDEPEND=" - ${COMMON_DEPEND} - $(python_gen_cond_dep ' - dev-python/bottle[${PYTHON_MULTI_USEDEP}] - dev-python/future[${PYTHON_MULTI_USEDEP}] - dev-python/jedi[${PYTHON_MULTI_USEDEP}] - dev-python/requests[${PYTHON_MULTI_USEDEP}] - dev-python/sh[${PYTHON_MULTI_USEDEP}] - dev-python/waitress[${PYTHON_MULTI_USEDEP}] - ') -" -DEPEND=" - ${COMMON_DEPEND} - test? ( - $(python_gen_cond_dep ' - >=dev-python/mock-1.0.1[${PYTHON_MULTI_USEDEP}] - >=dev-python/nose-1.3.0[${PYTHON_MULTI_USEDEP}] - dev-cpp/gmock - dev-cpp/gtest - ') - ) -" - -S="${WORKDIR}/YouCompleteMe-$youcompletemev" -CMAKE_IN_SOURCE_BUILD=1 -CMAKE_USE_DIR=${S}/third_party/ycmd/cpp - -VIM_PLUGIN_HELPFILES="${PN}" - -src_prepare() { - echo $RDEPEND - echo $DEPEND - - eapply ${FILESDIR}/remove-python2-support.patch - for third_party_module in ycmd requests-futures; do - rm -r "${S}"/third_party/${third_party_module} || die "Failed to remove third party module ${third_party_module}" - done - mv ${WORKDIR}/ycmd-$ycmdv ${S}/third_party/ycmd - use csharp && mv ${WORKDIR}/omnisharp-server-$ossv ${S}/third_party/ycmd/third_party/omnisharp-server - use go && mv ${WORKDIR}/gocode-$gocodev ${S}/third_party/ycmd/third_party/gocode - mv ${WORKDIR}/requests-futures-$reqfuv ${S}/third_party/requests-futures - cmake-utils_src_prepare - default -} - -src_configure() { - local mycmakeargs=( - -DUSE_CLANG_COMPLETER=$(usex clang) - -DUSE_SYSTEM_LIBCLANG=$(usex clang) - -DPATH_TO_LLVM_ROOT=$(clang --version | grep ^InstalledDir: | cut -d: -f2 | xargs dirname) - -DUSE_SYSTEM_BOOST=ON - ) - cmake-utils_src_configure -} - -src_test() { - cd "${S}/third_party/ycmd/cpp/ycm/tests" - LD_LIBRARY_PATH="${EROOT}"/usr/$(get_libdir)/llvm \ - ./ycm_core_tests || die - - cd "${S}"/python/ycm - - local dirs=( "${S}"/third_party/*/ "${S}"/third_party/ycmd/third_party/*/ ) - local -x PYTHONPATH=${PYTHONPATH}:$(IFS=:; echo "${dirs[*]}") - - nosetests || die -} - -src_install() { - dodoc *.md third_party/ycmd/*.md - rm -r *.md *.sh COPYING.txt third_party/ycmd/cpp || die - rm -r third_party/ycmd/{*.md,*.sh} || die - find python third_party/ycmd -depth -name '*test*' -exec rm -r {} + || die - find python third_party/ycmd -depth -name '*examples*' -exec rm -r {} + || die - rm third_party/ycmd/third_party/clang/lib/libclang.so.* || die - - vim-plugin_src_install - - python_optimize "${ED}" - python_fix_shebang "${ED}" -} diff --git a/app-vim/youcompleteme/youcompleteme-20220113.ebuild b/app-vim/youcompleteme/youcompleteme-20220113.ebuild new file mode 100644 index 0000000..6eba953 --- /dev/null +++ b/app-vim/youcompleteme/youcompleteme-20220113.ebuild @@ -0,0 +1,85 @@ +EAPI="7" +PYTHON_COMPAT=( python3_{9,10} ) +inherit multilib python-single-r1 cmake-utils vim-plugin + +youcompletemev="7684b6c6b49f8d3bdbd17ecdc9ee7d228039808e" +ycmdv="f7ba6e791829c2ad0a3b77bd8e921f2b4c71d7dc" + +KEYWORDS="~amd64 ~x86" +SRC_URI=" + https://github.com/ycm-core/YouCompleteMe/archive/$youcompletemev.tar.gz -> youcompleteme-$youcompletemev.tar.gz + https://github.com/ycm-core/ycmd/archive/$ycmdv.tar.gz -> ycmd-$ycmdv.tar.gz +" + +DESCRIPTION="vim plugin: a code-completion engine for Vim" +HOMEPAGE="http://ycm-core.github.io/YouCompleteMe/" + +LICENSE="GPL-3" +IUSE="+clang" + +COMMON_DEPEND=" + ${PYTHON_DEPS} + dev-cpp/abseil-cpp + clang? ( sys-devel/clang:13 ) + $(python_gen_cond_dep ' + >=dev-libs/boost-1.65:=[python,${PYTHON_MULTI_USEDEP}] + || ( + app-editors/vim[python,${PYTHON_SINGLE_USEDEP}] + app-editors/gvim[python,${PYTHON_SINGLE_USEDEP}] + ) + ') +" +RDEPEND=" + ${COMMON_DEPEND} + $(python_gen_cond_dep ' + >=dev-python/bottle-0.12.18[${PYTHON_MULTI_USEDEP}] + >=dev-python/regex-2020.2.20[${PYTHON_MULTI_USEDEP}] + >=dev-python/jedi-0.16.0[${PYTHON_MULTI_USEDEP}] + >=dev-python/watchdog-0.10.2[${PYTHON_MULTI_USEDEP}] + ') +" +DEPEND=" + ${COMMON_DEPEND} +" + +S="${WORKDIR}/YouCompleteMe-$youcompletemev" +CMAKE_IN_SOURCE_BUILD=1 +CMAKE_USE_DIR=${S}/third_party/ycmd/cpp + +VIM_PLUGIN_HELPFILES="${PN}" + +src_prepare() { + for third_party_module in ycmd ; do + rm -r "${S}"/third_party/${third_party_module} || die "Failed to remove third party module ${third_party_module}" + done + mv ${WORKDIR}/ycmd-$ycmdv ${S}/third_party/ycmd + cmake-utils_src_prepare + default +} + +src_configure() { + local mycmakeargs=( + -DUSE_CLANG_COMPLETER=$(usex clang) + -DUSE_SYSTEM_LIBCLANG=$(usex clang) + -DPATH_TO_LLVM_ROOT=$(clang-13 --version | grep ^InstalledDir: | cut -d: -f2 | xargs dirname) + -DUSE_SYSTEM_ABSEIL=ON + -DPython3_LIBRARY=$SYSROOT/usr/$(get_libdir)/lib$EPYTHON.so + -DPython3_EXECUTABLE=$SYSROOT/usr/bin/$EPYTHON + -DPython3_INCLUDE_DIR=$SYSROOT/usr/include/$EPYTHON + ) + cmake-utils_src_configure +} + +src_install() { + dodoc *.md third_party/ycmd/*.md + rm -r *.md *.sh COPYING.txt third_party/ycmd/cpp || die + rm -r third_party/ycmd/{*.md,*.sh} || die + rm -r test || die + find python third_party/ycmd -depth -name '*test*' -exec rm -r {} + || die + find python third_party/ycmd -depth -name '*examples*' -exec rm -r {} + || die + + vim-plugin_src_install + + python_optimize "${ED}" + python_fix_shebang "${ED}" +} -- cgit v1.2.3