aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabian Groffen <grobian@gentoo.org>2020-08-02 13:17:47 +0200
committerFabian Groffen <grobian@gentoo.org>2020-08-02 14:32:49 +0200
commit0d9cd144937a2a4388cb299fbcd753257b085970 (patch)
treed6fe48fc6fff0ded98af3110fb3061cf19d27620
parentMerge remote-tracking branch 'overlays-gentoo-org/master' into prefix (diff)
parentFix R0205 across all of repo. (diff)
downloadportage-0d9cd144.tar.gz
portage-0d9cd144.tar.bz2
portage-0d9cd144.zip
Merge remote-tracking branch 'overlays-gentoo-org/master' into prefix
Signed-off-by: Fabian Groffen <grobian@gentoo.org>
-rw-r--r--.travis.yml1
-rw-r--r--NEWS11
-rw-r--r--README2
-rw-r--r--RELEASE-NOTES43
-rwxr-xr-xbin/binhost-snapshot5
-rwxr-xr-xbin/check-implicit-pointer-usage.py25
-rwxr-xr-xbin/chmod-lite.py11
-rwxr-xr-xbin/chpathtool.py10
-rwxr-xr-xbin/dispatch-conf2
-rwxr-xr-xbin/dohtml.py13
-rw-r--r--bin/doins.py31
-rwxr-xr-xbin/ebuild15
-rwxr-xr-xbin/ebuild-ipc.py2
-rwxr-xr-xbin/ecompress36
-rwxr-xr-xbin/egencache17
-rwxr-xr-xbin/filter-bash-environment.py11
-rwxr-xr-xbin/glsa-check2
-rwxr-xr-xbin/install.py19
-rw-r--r--bin/pid-ns-init10
-rwxr-xr-xbin/portageq4
-rwxr-xr-xbin/quickpkg2
-rw-r--r--bin/socks5-server.py2
-rwxr-xr-xbin/xattr-helper.py32
-rw-r--r--lib/_emerge/AbstractEbuildProcess.py3
-rw-r--r--lib/_emerge/AbstractPollTask.py1
-rw-r--r--lib/_emerge/AsynchronousLock.py12
-rw-r--r--lib/_emerge/BinpkgFetcher.py14
-rw-r--r--lib/_emerge/BinpkgPrefetcher.py1
-rw-r--r--lib/_emerge/BlockerCache.py29
-rw-r--r--lib/_emerge/BlockerDB.py7
-rw-r--r--lib/_emerge/DepPriority.py1
-rw-r--r--lib/_emerge/DepPriorityNormalRange.py2
-rw-r--r--lib/_emerge/DepPrioritySatisfiedRange.py2
-rw-r--r--lib/_emerge/Dependency.py1
-rw-r--r--lib/_emerge/DependencyArg.py17
-rw-r--r--lib/_emerge/EbuildBuild.py26
-rw-r--r--lib/_emerge/EbuildBuildDir.py1
-rw-r--r--lib/_emerge/EbuildExecuter.py1
-rw-r--r--lib/_emerge/EbuildFetcher.py15
-rw-r--r--lib/_emerge/EbuildMetadataPhase.py12
-rw-r--r--lib/_emerge/EbuildPhase.py53
-rw-r--r--lib/_emerge/FakeVartree.py16
-rw-r--r--lib/_emerge/FifoIpcDaemon.py31
-rw-r--r--lib/_emerge/JobStatusDisplay.py15
-rw-r--r--lib/_emerge/MergeListItem.py2
-rw-r--r--lib/_emerge/Package.py46
-rw-r--r--lib/_emerge/PackageVirtualDbapi.py7
-rw-r--r--lib/_emerge/PipeReader.py14
-rw-r--r--lib/_emerge/PollScheduler.py2
-rw-r--r--lib/_emerge/ProgressHandler.py3
-rw-r--r--lib/_emerge/RootConfig.py2
-rw-r--r--lib/_emerge/Scheduler.py9
-rw-r--r--lib/_emerge/SequentialTaskQueue.py4
-rw-r--r--lib/_emerge/SetArg.py1
-rw-r--r--lib/_emerge/SpawnProcess.py85
-rw-r--r--lib/_emerge/SubProcess.py9
-rw-r--r--lib/_emerge/TaskSequence.py6
-rw-r--r--lib/_emerge/UnmergeDepPriority.py1
-rw-r--r--lib/_emerge/UseFlagDisplay.py15
-rw-r--r--lib/_emerge/UserQuery.py23
-rw-r--r--lib/_emerge/_find_deep_system_runtime_deps.py1
-rw-r--r--lib/_emerge/actions.py44
-rw-r--r--lib/_emerge/create_depgraph_params.py1
-rw-r--r--lib/_emerge/create_world_atom.py10
-rw-r--r--lib/_emerge/depgraph.py167
-rw-r--r--lib/_emerge/emergelog.py3
-rw-r--r--lib/_emerge/help.py2
-rw-r--r--lib/_emerge/main.py14
-rw-r--r--lib/_emerge/resolver/DbapiProvidesIndex.py8
-rw-r--r--lib/_emerge/resolver/backtracking.py9
-rw-r--r--lib/_emerge/resolver/circular_dependency.py4
-rw-r--r--lib/_emerge/resolver/output.py65
-rw-r--r--lib/_emerge/resolver/output_helpers.py35
-rw-r--r--lib/_emerge/resolver/package_tracker.py4
-rw-r--r--lib/_emerge/resolver/slot_collision.py85
-rw-r--r--lib/_emerge/search.py9
-rw-r--r--lib/_emerge/show_invalid_depstring_notice.py1
-rw-r--r--lib/_emerge/stdout_spinner.py2
-rw-r--r--lib/_emerge/unmerge.py5
-rw-r--r--lib/portage/__init__.py67
-rw-r--r--lib/portage/_emirrordist/Config.py11
-rw-r--r--lib/portage/_emirrordist/DeletionIterator.py2
-rw-r--r--lib/portage/_emirrordist/FetchIterator.py2
-rw-r--r--lib/portage/_emirrordist/FetchTask.py51
-rw-r--r--lib/portage/_emirrordist/MirrorDistTask.py8
-rw-r--r--lib/portage/_emirrordist/main.py9
-rw-r--r--lib/portage/_global_updates.py3
-rw-r--r--lib/portage/_legacy_globals.py2
-rw-r--r--lib/portage/_selinux.py15
-rw-r--r--lib/portage/_sets/__init__.py9
-rw-r--r--lib/portage/_sets/base.py16
-rw-r--r--lib/portage/_sets/dbapi.py51
-rw-r--r--lib/portage/cache/__init__.py1
-rw-r--r--lib/portage/cache/anydbm.py36
-rw-r--r--lib/portage/cache/ebuild_xattr.py35
-rw-r--r--lib/portage/cache/flat_hash.py8
-rw-r--r--lib/portage/cache/fs_template.py13
-rw-r--r--lib/portage/cache/index/IndexStreamIterator.py2
-rw-r--r--lib/portage/cache/index/pkg_desc_index.py13
-rw-r--r--lib/portage/cache/mappings.py54
-rw-r--r--lib/portage/cache/metadata.py9
-rw-r--r--lib/portage/cache/sql_template.py6
-rw-r--r--lib/portage/cache/sqlite.py15
-rw-r--r--lib/portage/cache/template.py34
-rw-r--r--lib/portage/checksum.py11
-rw-r--r--lib/portage/const.py2
-rw-r--r--lib/portage/cvstree.py19
-rw-r--r--lib/portage/data.py10
-rw-r--r--lib/portage/dbapi/DummyTree.py2
-rw-r--r--lib/portage/dbapi/IndexedPortdb.py7
-rw-r--r--lib/portage/dbapi/IndexedVardb.py5
-rw-r--r--lib/portage/dbapi/_ContentsCaseSensitivityManager.py2
-rw-r--r--lib/portage/dbapi/_MergeProcess.py128
-rw-r--r--lib/portage/dbapi/_VdbMetadataDelta.py2
-rw-r--r--lib/portage/dbapi/__init__.py4
-rw-r--r--lib/portage/dbapi/_expand_new_virt.py2
-rw-r--r--lib/portage/dbapi/bintree.py81
-rw-r--r--lib/portage/dbapi/cpv_expand.py8
-rw-r--r--lib/portage/dbapi/dep_expand.py2
-rw-r--r--lib/portage/dbapi/porttree.py42
-rw-r--r--lib/portage/dbapi/vartree.py88
-rw-r--r--lib/portage/dbapi/virtual.py7
-rw-r--r--lib/portage/debug.py16
-rw-r--r--lib/portage/dep/__init__.py211
-rw-r--r--lib/portage/dep/_dnf.py4
-rw-r--r--lib/portage/dep/_slot_operator.py2
-rw-r--r--lib/portage/dep/dep_check.py15
-rw-r--r--lib/portage/dep/soname/SonameAtom.py13
-rw-r--r--lib/portage/dep/soname/multilib_category.py2
-rw-r--r--lib/portage/dep/soname/parse.py2
-rw-r--r--lib/portage/dispatch_conf.py4
-rw-r--r--lib/portage/eclass_cache.py17
-rw-r--r--lib/portage/elog/__init__.py6
-rw-r--r--lib/portage/elog/messages.py5
-rw-r--r--lib/portage/elog/mod_echo.py5
-rw-r--r--lib/portage/elog/mod_mail_summary.py4
-rw-r--r--lib/portage/elog/mod_save_summary.py5
-rw-r--r--lib/portage/elog/mod_syslog.py10
-rw-r--r--lib/portage/emaint/main.py4
-rw-r--r--lib/portage/emaint/modules/binhost/binhost.py12
-rw-r--r--lib/portage/emaint/modules/config/config.py2
-rw-r--r--lib/portage/emaint/modules/logs/logs.py2
-rw-r--r--lib/portage/emaint/modules/merges/merges.py8
-rw-r--r--lib/portage/emaint/modules/move/move.py2
-rw-r--r--lib/portage/emaint/modules/resume/resume.py2
-rw-r--r--lib/portage/emaint/modules/sync/sync.py13
-rw-r--r--lib/portage/emaint/modules/world/world.py3
-rw-r--r--lib/portage/env/__init__.py1
-rw-r--r--lib/portage/env/loaders.py2
-rw-r--r--lib/portage/exception.py53
-rw-r--r--lib/portage/getbinpkg.py55
-rw-r--r--lib/portage/glsa.py16
-rw-r--r--lib/portage/locks.py46
-rw-r--r--lib/portage/mail.py57
-rw-r--r--lib/portage/manifest.py37
-rw-r--r--lib/portage/metadata.py2
-rw-r--r--lib/portage/module.py4
-rw-r--r--lib/portage/news.py8
-rw-r--r--lib/portage/output.py49
-rw-r--r--lib/portage/package/ebuild/_config/KeywordsManager.py2
-rw-r--r--lib/portage/package/ebuild/_config/LicenseManager.py2
-rw-r--r--lib/portage/package/ebuild/_config/LocationsManager.py4
-rw-r--r--lib/portage/package/ebuild/_config/MaskManager.py2
-rw-r--r--lib/portage/package/ebuild/_config/UseManager.py2
-rw-r--r--lib/portage/package/ebuild/_config/VirtualsManager.py2
-rw-r--r--lib/portage/package/ebuild/_config/features_set.py2
-rw-r--r--lib/portage/package/ebuild/_config/special_env_vars.py10
-rw-r--r--lib/portage/package/ebuild/_ipc/IpcCommand.py2
-rw-r--r--lib/portage/package/ebuild/_ipc/QueryCommand.py17
-rw-r--r--lib/portage/package/ebuild/_parallel_manifest/ManifestProcess.py3
-rw-r--r--lib/portage/package/ebuild/_parallel_manifest/ManifestScheduler.py2
-rw-r--r--lib/portage/package/ebuild/config.py51
-rw-r--r--lib/portage/package/ebuild/doebuild.py20
-rw-r--r--lib/portage/package/ebuild/fetch.py28
-rw-r--r--lib/portage/package/ebuild/getmaskingreason.py9
-rw-r--r--lib/portage/package/ebuild/getmaskingstatus.py16
-rw-r--r--lib/portage/package/ebuild/prepare_build_dirs.py2
-rw-r--r--lib/portage/process.py29
-rw-r--r--lib/portage/progress.py3
-rw-r--r--lib/portage/proxy/lazyimport.py7
-rw-r--r--lib/portage/proxy/objectproxy.py11
-rw-r--r--lib/portage/repository/config.py43
-rw-r--r--lib/portage/repository/storage/hardlink_rcu.py13
-rw-r--r--lib/portage/repository/storage/interface.py2
-rw-r--r--lib/portage/sync/config_checks.py2
-rw-r--r--lib/portage/sync/controller.py12
-rw-r--r--lib/portage/sync/getaddrinfo_validate.py7
-rw-r--r--lib/portage/sync/modules/git/__init__.py13
-rw-r--r--lib/portage/sync/modules/git/git.py37
-rw-r--r--lib/portage/sync/modules/rsync/rsync.py14
-rw-r--r--lib/portage/sync/modules/webrsync/webrsync.py1
-rw-r--r--lib/portage/sync/syncbase.py12
-rw-r--r--lib/portage/tests/bin/setup_env.py20
-rw-r--r--lib/portage/tests/dbapi/test_auxdb.py2
-rw-r--r--lib/portage/tests/dep/testAtom.py2
-rw-r--r--lib/portage/tests/dep/test_isvalidatom.py2
-rw-r--r--lib/portage/tests/dep/test_match_from_list.py14
-rw-r--r--lib/portage/tests/dep/test_soname_atom_pickle.py3
-rw-r--r--lib/portage/tests/dep/test_use_reduce.py2
-rw-r--r--lib/portage/tests/ebuild/test_config.py2
-rw-r--r--lib/portage/tests/ebuild/test_fetch.py6
-rw-r--r--lib/portage/tests/ebuild/test_spawn.py1
-rw-r--r--lib/portage/tests/ebuild/test_use_expand_incremental.py2
-rw-r--r--lib/portage/tests/emerge/test_config_protect.py2
-rw-r--r--lib/portage/tests/env/__init__.py1
-rw-r--r--lib/portage/tests/env/config/__init__.py1
-rw-r--r--lib/portage/tests/glsa/test_security_set.py2
-rw-r--r--lib/portage/tests/lint/test_bash_syntax.py1
-rw-r--r--lib/portage/tests/process/test_AsyncFunction.py38
-rw-r--r--lib/portage/tests/process/test_PipeLogger.py58
-rw-r--r--lib/portage/tests/process/test_poll.py10
-rw-r--r--lib/portage/tests/resolver/ResolverPlayground.py19
-rw-r--r--lib/portage/tests/resolver/test_binary_pkg_ebuild_visibility.py1
-rw-r--r--lib/portage/tests/resolver/test_profile_default_eapi.py2
-rw-r--r--lib/portage/tests/resolver/test_profile_package_set.py2
-rw-r--r--lib/portage/tests/sets/files/testConfigFileSet.py1
-rw-r--r--lib/portage/tests/sets/files/testStaticFileSet.py1
-rw-r--r--lib/portage/tests/sets/shell/testShell.py8
-rw-r--r--lib/portage/tests/sync/test_sync_local.py11
-rw-r--r--lib/portage/tests/unicode/test_string_format.py54
-rw-r--r--lib/portage/tests/util/__init__.py1
-rw-r--r--lib/portage/tests/util/futures/asyncio/test_pipe_closed.py10
-rw-r--r--lib/portage/tests/util/futures/asyncio/test_policy_wrapper_recursion.py8
-rw-r--r--lib/portage/tests/util/futures/asyncio/test_subprocess_exec.py5
-rw-r--r--lib/portage/tests/util/futures/test_compat_coroutine.py2
-rw-r--r--lib/portage/tests/util/futures/test_retry.py34
-rw-r--r--lib/portage/tests/util/test_socks5.py31
-rw-r--r--lib/portage/tests/util/test_xattr.py14
-rw-r--r--lib/portage/update.py18
-rw-r--r--lib/portage/util/SlotObject.py2
-rw-r--r--lib/portage/util/_ShelveUnicodeWrapper.py45
-rw-r--r--lib/portage/util/__init__.py109
-rw-r--r--lib/portage/util/_async/AsyncFunction.py4
-rw-r--r--lib/portage/util/_async/BuildLogger.py109
-rw-r--r--lib/portage/util/_async/ForkProcess.py146
-rw-r--r--lib/portage/util/_async/PipeLogger.py160
-rw-r--r--lib/portage/util/_async/SchedulerInterface.py32
-rw-r--r--lib/portage/util/_compare_files.py23
-rw-r--r--lib/portage/util/_desktop_entry.py8
-rw-r--r--lib/portage/util/_dyn_libs/LinkageMapELF.py48
-rw-r--r--lib/portage/util/_dyn_libs/NeededEntry.py15
-rw-r--r--lib/portage/util/_dyn_libs/PreservedLibsRegistry.py21
-rw-r--r--lib/portage/util/_dyn_libs/soname_deps.py4
-rw-r--r--lib/portage/util/_eventloop/EventLoop.py50
-rw-r--r--lib/portage/util/_eventloop/PollConstants.py3
-rw-r--r--lib/portage/util/_eventloop/PollSelectAdapter.py3
-rw-r--r--lib/portage/util/_eventloop/asyncio_event_loop.py9
-rw-r--r--lib/portage/util/_eventloop/global_event_loop.py16
-rw-r--r--lib/portage/util/_urlopen.py67
-rw-r--r--lib/portage/util/_xattr.py2
-rw-r--r--lib/portage/util/backoff.py2
-rw-r--r--lib/portage/util/changelog.py29
-rw-r--r--lib/portage/util/compression_probe.py5
-rw-r--r--lib/portage/util/configparser.py23
-rw-r--r--lib/portage/util/digraph.py8
-rw-r--r--lib/portage/util/elf/header.py2
-rw-r--r--lib/portage/util/env_update.py8
-rw-r--r--lib/portage/util/formatter.py5
-rw-r--r--lib/portage/util/futures/_asyncio/__init__.py48
-rw-r--r--lib/portage/util/futures/_asyncio/process.py15
-rw-r--r--lib/portage/util/futures/_asyncio/streams.py52
-rw-r--r--lib/portage/util/futures/_asyncio/tasks.py9
-rw-r--r--lib/portage/util/futures/compat_coroutine.py3
-rw-r--r--lib/portage/util/futures/events.py37
-rw-r--r--lib/portage/util/futures/executor/fork.py2
-rw-r--r--lib/portage/util/futures/extendedfutures.py2
-rw-r--r--lib/portage/util/futures/futures.py42
-rw-r--r--lib/portage/util/futures/retry.py2
-rw-r--r--lib/portage/util/futures/transports.py5
-rw-r--r--lib/portage/util/futures/unix_events.py34
-rw-r--r--lib/portage/util/install_mask.py13
-rw-r--r--lib/portage/util/iterators/MultiIterGroupBy.py4
-rw-r--r--lib/portage/util/lafilefixer.py11
-rw-r--r--lib/portage/util/listdir.py3
-rw-r--r--lib/portage/util/locale.py2
-rw-r--r--lib/portage/util/monotonic.py34
-rw-r--r--lib/portage/util/movefile.py65
-rw-r--r--lib/portage/util/mtimedb.py6
-rw-r--r--lib/portage/util/socks5.py2
-rw-r--r--lib/portage/util/whirlpool.py26
-rw-r--r--lib/portage/util/writeable_check.py2
-rw-r--r--lib/portage/versions.py40
-rw-r--r--lib/portage/xml/metadata.py24
-rw-r--r--lib/portage/xpak.py5
-rw-r--r--man/ebuild.54
-rw-r--r--man/egencache.14
-rw-r--r--man/emerge.18
-rw-r--r--man/make.conf.57
-rw-r--r--man/portage.554
-rw-r--r--pylintrc464
-rw-r--r--repoman/RELEASE-NOTES5
-rw-r--r--repoman/lib/repoman/__init__.py7
-rw-r--r--repoman/lib/repoman/actions.py4
-rw-r--r--repoman/lib/repoman/copyrights.py2
-rw-r--r--repoman/lib/repoman/errors.py2
-rw-r--r--repoman/lib/repoman/gpg.py2
-rwxr-xr-xrepoman/lib/repoman/main.py4
-rw-r--r--repoman/lib/repoman/metadata.py7
-rw-r--r--repoman/lib/repoman/modules/commit/manifest.py2
-rw-r--r--repoman/lib/repoman/modules/commit/repochecks.py2
-rw-r--r--repoman/lib/repoman/modules/linechecks/base.py2
-rw-r--r--repoman/lib/repoman/modules/linechecks/config.py4
-rw-r--r--repoman/lib/repoman/modules/linechecks/controller.py2
-rw-r--r--repoman/lib/repoman/modules/linechecks/deprecated/inherit.py2
-rw-r--r--repoman/lib/repoman/modules/scan/ebuild/ebuild.py2
-rw-r--r--repoman/lib/repoman/modules/scan/metadata/ebuild_metadata.py5
-rw-r--r--repoman/lib/repoman/modules/scan/metadata/use_flags.py2
-rw-r--r--repoman/lib/repoman/modules/scan/module.py2
-rw-r--r--repoman/lib/repoman/modules/scan/scanbase.py2
-rw-r--r--repoman/lib/repoman/modules/vcs/None/status.py2
-rw-r--r--repoman/lib/repoman/modules/vcs/bzr/status.py2
-rw-r--r--repoman/lib/repoman/modules/vcs/changes.py2
-rw-r--r--repoman/lib/repoman/modules/vcs/cvs/status.py2
-rw-r--r--repoman/lib/repoman/modules/vcs/git/status.py2
-rw-r--r--repoman/lib/repoman/modules/vcs/hg/status.py2
-rw-r--r--repoman/lib/repoman/modules/vcs/settings.py4
-rw-r--r--repoman/lib/repoman/modules/vcs/svn/status.py2
-rw-r--r--repoman/lib/repoman/modules/vcs/vcs.py2
-rw-r--r--repoman/lib/repoman/profile.py4
-rw-r--r--repoman/lib/repoman/qa_data.py2
-rw-r--r--repoman/lib/repoman/qa_tracker.py2
-rw-r--r--repoman/lib/repoman/repos.py2
-rw-r--r--repoman/lib/repoman/scanner.py4
-rw-r--r--repoman/lib/repoman/utilities.py5
-rwxr-xr-xrepoman/setup.py4
-rwxr-xr-xruntests3
-rwxr-xr-xsetup.py4
-rw-r--r--tox.ini6
328 files changed, 2638 insertions, 3095 deletions
diff --git a/.travis.yml b/.travis.yml
index 6d3afa4ce..b9f6c85f7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,6 @@
dist: bionic
language: python
python:
- - 2.7
- 3.6
- 3.7
- 3.8
diff --git a/NEWS b/NEWS
index 4392f4c44..1d609bd31 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,16 @@
News (mainly features/major bug fixes)
+portage-3.0.0
+--------------
+* Dropped support for Python 2.x.
+
+portage-2.3.101
+--------------
+* The new PORTAGE_LOG_FILTER_FILE_CMD make.conf(5) variable specifies a
+ command that filters build log output to a log file. In order to
+ filter ANSI escape codes from build logs, ansifilter(1) is a
+ convenient setting for this variable.
+
portage-2.3.100
--------------
* New BINPKG_COMPRESS=zstd default (does not apply to installed systems
diff --git a/README b/README
index 4ab10c6b5..5b2acbbaf 100644
--- a/README
+++ b/README
@@ -19,7 +19,7 @@ other package managers.
Dependencies
============
-Python and Bash should be the only hard dependencies. Python 2.7 is the
+Python and Bash should be the only hard dependencies. Python 3.6 is the
minimum supported version.
Native Extensions
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index cf4a04c29..228da8e77 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -1,6 +1,49 @@
Release Notes; upgrade information mainly.
Features/major bugfixes are listed in NEWS
+portage-3.0.1
+==================================
+* Bug Fixes:
+ - Bug 730192 Replace os.fork with multiprocessing.Process, and fix
+ regression in portage-3.0.0 involving eerror messages for fetch
+ failures
+
+portage-3.0.0
+==================================
+* Bug Fixes:
+ - Bug 703698 Improve repos.conf handling of boolean settings
+ - Bug 721516 ecompress complains about compressed files that have
+ been excluded by docompress -x
+ - Bug 729852 Set XTerm titles for konsole
+ - Bug 731114 Drop support for python2.7
+ - Bug 731246 man ebuild(5) has incorrect example of $P and $PN
+ - Bug 732378 Use lru_cache for use_reduce, vercmp, and catpkgsplit
+ - Bug 733154 List of ignored warnings in .desktop files should be
+ updated for compatibility with >=desktop-file-utils-0.25
+
+portage-2.3.103
+==================================
+* Bug Fixes:
+ - Bug 709746 set non-blocking for build_logger stdin in EbuildPhase
+ _elog method
+ - Bug 727522 ecompress: fix "Argument list too long" for sed
+
+portage-2.3.102
+==================================
+* Bug Fixes:
+ - Bug 716636 Fix emerge hang triggered by unsafe remove_reader and
+ remove_writer calls related to bug 709746
+
+portage-2.3.101
+==================================
+* Bug Fixes:
+ - Bug 661518 repos.conf: Add bool sync-openpgp-key-refresh option
+ - Bug 709746 New PORTAGE_LOG_FILTER_FILE_CMD variable specifies a
+ command that filters build log output to a log file
+ - Bug 719810 Escape percent-signs in mirror url
+ - Bug 725934 _better_cache._scan_cat: Avoid stat calls
+ - Bug 728046 ecompress: Prefix eqawarn messages with QA Notice
+
portage-2.3.100
==================================
* Bug Fixes:
diff --git a/bin/binhost-snapshot b/bin/binhost-snapshot
index 41d556831..fbecfa8bb 100755
--- a/bin/binhost-snapshot
+++ b/bin/binhost-snapshot
@@ -8,10 +8,7 @@ import os
import sys
import textwrap
-try:
- from urllib.parse import urlparse
-except ImportError:
- from urlparse import urlparse
+from urllib.parse import urlparse
from os import path as osp
if osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), ".portage_not_installed")):
diff --git a/bin/check-implicit-pointer-usage.py b/bin/check-implicit-pointer-usage.py
index 7921d005d..208b3ac97 100755
--- a/bin/check-implicit-pointer-usage.py
+++ b/bin/check-implicit-pointer-usage.py
@@ -33,22 +33,10 @@ pointer_pattern = (
+ r"|"
+ r"cast to pointer from integer of different size)")
-if sys.hexversion < 0x3000000:
- # Use encoded byte strings in python-2.x, since the python ebuilds are
- # known to remove the encodings module when USE=build is enabled (thus
- # disabling unicode decoding/encoding). The portage module has a
- # workaround for this, but currently we don't import that here since we
- # don't want to trigger potential sandbox violations due to stale pyc
- # files for the portage module.
- unicode_quote_open = '\xE2\x80\x98'
- unicode_quote_close = '\xE2\x80\x99'
- def write(msg):
- sys.stdout.write(msg)
-else:
- unicode_quote_open = '\u2018'
- unicode_quote_close = '\u2019'
- def write(msg):
- sys.stdout.buffer.write(msg.encode('utf_8', 'backslashreplace'))
+unicode_quote_open = '\u2018'
+unicode_quote_close = '\u2019'
+def write(msg):
+ sys.stdout.buffer.write(msg.encode('utf_8', 'backslashreplace'))
pointer_pattern = re.compile(pointer_pattern)
@@ -57,10 +45,7 @@ last_implicit_linenum = -1
last_implicit_func = ""
while True:
- if sys.hexversion >= 0x3000000:
- line = sys.stdin.buffer.readline().decode('utf_8', 'replace')
- else:
- line = sys.stdin.readline()
+ line = sys.stdin.buffer.readline().decode('utf_8', 'replace')
if not line:
break
# translate unicode open/close quotes to ascii ones
diff --git a/bin/chmod-lite.py b/bin/chmod-lite.py
index b9a4fc9a2..d4dad8401 100755
--- a/bin/chmod-lite.py
+++ b/bin/chmod-lite.py
@@ -12,12 +12,11 @@ os.chdir(os.environ["__PORTAGE_HELPER_CWD"])
def main(files):
- if sys.hexversion >= 0x3000000:
- # We can't trust that the filesystem encoding (locale dependent)
- # correctly matches the arguments, so use surrogateescape to
- # pass through the original argv bytes for Python 3.
- fs_encoding = sys.getfilesystemencoding()
- files = [x.encode(fs_encoding, 'surrogateescape') for x in files]
+ # We can't trust that the filesystem encoding (locale dependent)
+ # correctly matches the arguments, so use surrogateescape to
+ # pass through the original argv bytes for Python 3.
+ fs_encoding = sys.getfilesystemencoding()
+ files = [x.encode(fs_encoding, 'surrogateescape') for x in files]
for filename in files:
# Emulate 'chmod -fR a+rX,u+w,g-w,o-w' with minimal chmod calls.
diff --git a/bin/chpathtool.py b/bin/chpathtool.py
index b9483b841..cd08ed58b 100755
--- a/bin/chpathtool.py
+++ b/bin/chpathtool.py
@@ -27,7 +27,7 @@ else:
# magic module seems to be broken
magic = None
-class IsTextFile(object):
+class IsTextFile:
def __init__(self):
if magic is not None:
@@ -128,12 +128,8 @@ def chpath_inplace(filename, is_text_file, old, new):
f.close()
if modified:
- if sys.hexversion >= 0x3030000:
- orig_mtime = orig_stat.st_mtime_ns
- os.utime(filename, ns=(orig_mtime, orig_mtime))
- else:
- orig_mtime = orig_stat[stat.ST_MTIME]
- os.utime(filename, (orig_mtime, orig_mtime))
+ orig_mtime = orig_stat.st_mtime_ns
+ os.utime(filename, ns=(orig_mtime, orig_mtime))
return modified
def chpath_inplace_symlink(filename, st, old, new):
diff --git a/bin/dispatch-conf b/bin/dispatch-conf
index c05215fc3..2a9db88a9 100755
--- a/bin/dispatch-conf
+++ b/bin/dispatch-conf
@@ -11,7 +11,7 @@
# dialog menus
#
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
import atexit
import io
diff --git a/bin/dohtml.py b/bin/dohtml.py
index f99cd9812..7be1241eb 100755
--- a/bin/dohtml.py
+++ b/bin/dohtml.py
@@ -28,7 +28,7 @@
# - will do as 'dohtml -r', but ignore directories named CVS, SCCS, RCS
#
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
import os as _os
import sys
@@ -163,12 +163,11 @@ def print_help():
def parse_args():
argv = sys.argv[:]
- if sys.hexversion >= 0x3000000:
- # We can't trust that the filesystem encoding (locale dependent)
- # correctly matches the arguments, so use surrogateescape to
- # pass through the original argv bytes for Python 3.
- fs_encoding = sys.getfilesystemencoding()
- argv = [x.encode(fs_encoding, 'surrogateescape') for x in argv]
+ # We can't trust that the filesystem encoding (locale dependent)
+ # correctly matches the arguments, so use surrogateescape to
+ # pass through the original argv bytes for Python 3.
+ fs_encoding = sys.getfilesystemencoding()
+ argv = [x.encode(fs_encoding, 'surrogateescape') for x in argv]
for x, arg in enumerate(argv):
try:
diff --git a/bin/doins.py b/bin/doins.py
index 6bc30c90b..4929cb90a 100644
--- a/bin/doins.py
+++ b/bin/doins.py
@@ -110,10 +110,6 @@ def _parse_install_options(
parser.add_argument('-p', '--preserve-timestamps', action='store_true')
split_options = shlex.split(options)
namespace, remaining = parser.parse_known_args(split_options)
- if namespace.preserve_timestamps and sys.version_info < (3, 3):
- # -p is not supported in this case, since timestamps cannot
- # be preserved with full precision
- remaining.append('-p')
# Because parsing '--mode' option is partially supported. If unknown
# arg for --mode is passed, namespace.mode is set to None.
if remaining or namespace.mode is None:
@@ -151,18 +147,10 @@ def _set_timestamps(source_stat, dest):
source_stat: stat result for the source file.
dest: path to the dest file.
"""
- os.utime(dest, (source_stat.st_atime, source_stat.st_mtime))
+ os.utime(dest, ns=(source_stat.st_atime_ns, source_stat.st_mtime_ns))
-if sys.version_info >= (3, 3):
- def _set_timestamps_ns(source_stat, dest):
- os.utime(dest, ns=(source_stat.st_atime_ns, source_stat.st_mtime_ns))
-
- _set_timestamps_ns.__doc__ = _set_timestamps.__doc__
- _set_timestamps = _set_timestamps_ns
-
-
-class _InsInProcessInstallRunner(object):
+class _InsInProcessInstallRunner:
"""Implements `install` command behavior running in a process."""
def __init__(self, opts, parsed_options):
@@ -269,7 +257,7 @@ class _InsInProcessInstallRunner(object):
return False
-class _InsSubprocessInstallRunner(object):
+class _InsSubprocessInstallRunner:
"""Runs `install` command in a subprocess to install a file."""
def __init__(self, split_options):
@@ -295,7 +283,7 @@ class _InsSubprocessInstallRunner(object):
return subprocess.call(command) == 0
-class _DirInProcessInstallRunner(object):
+class _DirInProcessInstallRunner:
"""Implements `install` command behavior running in a process."""
def __init__(self, parsed_options):
@@ -321,7 +309,7 @@ class _DirInProcessInstallRunner(object):
_set_attributes(self._parsed_options, dest)
-class _DirSubprocessInstallRunner(object):
+class _DirSubprocessInstallRunner:
"""Runs `install` command to create a directory."""
def __init__(self, split_options):
@@ -343,7 +331,7 @@ class _DirSubprocessInstallRunner(object):
subprocess.check_call(command)
-class _InstallRunner(object):
+class _InstallRunner:
"""Handles `install` command operation.
Runs operations which `install` command should work. If possible,
@@ -514,10 +502,9 @@ def _parse_args(argv):
# Encode back to the original byte stream. Please see
# http://bugs.python.org/issue8776.
- if sys.version_info.major >= 3:
- opts.distdir = os.fsencode(opts.distdir) + b'/'
- opts.dest = os.fsencode(opts.dest)
- opts.sources = [os.fsencode(source) for source in opts.sources]
+ opts.distdir = os.fsencode(opts.distdir) + b'/'
+ opts.dest = os.fsencode(opts.dest)
+ opts.sources = [os.fsencode(source) for source in opts.sources]
return opts
diff --git a/bin/ebuild b/bin/ebuild
index a57dd4941..d3961ddc5 100755
--- a/bin/ebuild
+++ b/bin/ebuild
@@ -144,9 +144,6 @@ if not os.path.isabs(ebuild):
# the canonical path returned from os.getcwd() may may be unusable in
# cases where the directory stucture is built from symlinks.
pwd = os.environ.get('PWD', '')
- if sys.hexversion < 0x3000000:
- pwd = _unicode_decode(pwd, encoding=_encodings['content'],
- errors='strict')
if pwd and pwd != mycwd and \
os.path.realpath(pwd) == mycwd:
mycwd = portage.normalize_path(pwd)
@@ -163,16 +160,8 @@ vdb_path = os.path.realpath(os.path.join(portage.settings['EROOT'], VDB_PATH))
if ebuild_portdir != vdb_path and \
ebuild_portdir not in portage.portdb.porttrees:
portdir_overlay = portage.settings.get("PORTDIR_OVERLAY", "")
- if sys.hexversion >= 0x3000000:
- os.environ["PORTDIR_OVERLAY"] = \
- portdir_overlay + \
- " " + _shell_quote(ebuild_portdir)
- else:
- os.environ["PORTDIR_OVERLAY"] = \
- _unicode_encode(portdir_overlay,
- encoding=_encodings['content'], errors='strict') + \
- " " + _unicode_encode(_shell_quote(ebuild_portdir),
- encoding=_encodings['content'], errors='strict')
+ os.environ["PORTDIR_OVERLAY"] = (
+ portdir_overlay + " " + _shell_quote(ebuild_portdir))
print("Appending %s to PORTDIR_OVERLAY..." % ebuild_portdir)
portage._reset_legacy_globals()
diff --git a/bin/ebuild-ipc.py b/bin/ebuild-ipc.py
index 773054f5d..c523572a7 100755
--- a/bin/ebuild-ipc.py
+++ b/bin/ebuild-ipc.py
@@ -100,7 +100,7 @@ class FifoWriter(AbstractPollTask):
os.close(self._fd)
self._fd = None
-class EbuildIpc(object):
+class EbuildIpc:
# Timeout for each individual communication attempt (we retry
# as long as the daemon process appears to be alive).
diff --git a/bin/ecompress b/bin/ecompress
index 2d74ed07a..7991bcfbe 100755
--- a/bin/ecompress
+++ b/bin/ecompress
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright 1999-2018 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH}"/isolated-functions.sh || exit 1
@@ -19,28 +19,30 @@ while [[ $# -gt 0 ]] ; do
shift
skip_dirs=()
- skip_files=()
+ > "${T}/.ecompress_skip_files" || die
for skip; do
if [[ -d ${ED%/}/${skip#/} ]]; then
skip_dirs+=( "${ED%/}/${skip#/}" )
else
rm -f "${ED%/}/${skip#/}.ecompress" || die
- skip_files+=("${ED%/}/${skip#/}")
+ printf -- '%s\n' "${EPREFIX}/${skip#/}" >> "${T}/.ecompress_skip_files" || die
fi
done
if [[ ${#skip_dirs[@]} -gt 0 ]]; then
- while read -r -d ''; do
- skip_files+=(${REPLY#.ecompress})
+ while read -r -d '' skip; do
+ skip=${skip%.ecompress}
+ printf -- '%s\n' "${skip#${D%/}}" >> "${T}/.ecompress_skip_files" || die
done < <(find "${skip_dirs[@]}" -name '*.ecompress' -print0 -delete || die)
fi
- if [[ ${#skip_files[@]} -gt 0 && -s ${T}/.ecompress_had_precompressed ]]; then
- sed_args=()
- for f in "${skip_files[@]}"; do
- sed_args+=(-e "s|^${f}\$||")
- done
- sed "${sed_args[@]}" -e '/^$/d' -i "${T}/.ecompress_had_precompressed" || die
+ if [[ -s ${T}/.ecompress_skip_files && -s ${T}/.ecompress_had_precompressed ]]; then
+ # Filter skipped files from ${T}/.ecompress_had_precompressed,
+ # using temporary files since these lists can be extremely large.
+ LC_COLLATE=C sort -u "${T}/.ecompress_skip_files" > "${T}/.ecompress_skip_files_sorted" || die
+ LC_COLLATE=C sort -u "${T}/.ecompress_had_precompressed" > "${T}/.ecompress_had_precompressed_sorted" || die
+ LC_COLLATE=C comm -13 "${T}/.ecompress_skip_files_sorted" "${T}/.ecompress_had_precompressed_sorted" > "${T}/.ecompress_had_precompressed" || die
+ rm -f "${T}/.ecompress_had_precompressed_sorted" "${T}/.ecompress_skip_files"{,_sorted}
fi
exit 0
@@ -80,7 +82,7 @@ while [[ $# -gt 0 ]] ; do
continue 2
fi
done
- echo "${path}" >> "${T}"/.ecompress_had_precompressed
+ printf -- '%s\n' "${path#${D%/}}" >> "${T}"/.ecompress_had_precompressed || die
;;
esac
@@ -88,7 +90,7 @@ while [[ $# -gt 0 ]] ; do
done < <(find "${find_args[@]}" -print0 || die)
if [[ ${#collisions[@]} -gt 0 ]]; then
- eqawarn "Colliding files found by ecompress:"
+ eqawarn "QA Notice: Colliding files found by ecompress:"
eqawarn
for x in "${!collisions[@]}"; do
eqawarn " ${x}"
@@ -189,13 +191,13 @@ find "${ED}" -name '*.ecompress' -delete -print0 |
ret=${?}
if [[ -s ${T}/.ecompress_had_precompressed ]]; then
- eqawarn "One or more compressed files were found in docompress-ed directories."
- eqawarn "Please fix the ebuild not to install compressed files (manpages,"
- eqawarn "documentation) when automatic compression is used:"
+ eqawarn "QA Notice: One or more compressed files were found in docompress-ed"
+ eqawarn "directories. Please fix the ebuild not to install compressed files"
+ eqawarn "(manpages, documentation) when automatic compression is used:"
eqawarn
n=0
while read -r f; do
- eqawarn " ${f#${D%/}}"
+ eqawarn " ${f}"
if [[ $(( n++ )) -eq 10 ]]; then
eqawarn " ..."
break
diff --git a/bin/egencache b/bin/egencache
index 04c8af2f0..1dc94b790 100755
--- a/bin/egencache
+++ b/bin/egencache
@@ -3,7 +3,7 @@
# Distributed under the terms of the GNU General Public License v2
# unicode_literals for compat with TextIOWrapper in Python 2
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
import argparse
import platform
@@ -75,9 +75,6 @@ else:
else:
from portage.xml.metadata import parse_metadata_use
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- long = int
def parse_args(args):
usage = "egencache [options] <action> ... [atom] ..."
@@ -241,7 +238,7 @@ def parse_args(args):
return parser, options, args
-class GenCache(object):
+class GenCache:
def __init__(self, portdb, cp_iter=None, max_jobs=None, max_load=None,
rsync=False):
# The caller must set portdb.porttrees in order to constrain
@@ -344,7 +341,7 @@ class GenCache(object):
max_mtime = ec_hash.mtime
if max_mtime == sc.mtime:
max_mtime += 1
- max_mtime = long(max_mtime)
+ max_mtime = int(max_mtime)
try:
os.utime(ebuild_hash.location, (max_mtime, max_mtime))
except OSError as e:
@@ -450,7 +447,7 @@ class GenCache(object):
if hasattr(trg_cache, '_prune_empty_dirs'):
trg_cache._prune_empty_dirs()
-class GenPkgDescIndex(object):
+class GenPkgDescIndex:
def __init__(self, portdb, output_file):
self.returncode = os.EX_OK
self._portdb = portdb
@@ -473,7 +470,7 @@ class GenPkgDescIndex(object):
f.close()
-class GenUseLocalDesc(object):
+class GenUseLocalDesc:
def __init__(self, portdb, output=None,
preserve_comments=False):
self.returncode = os.EX_OK
@@ -668,7 +665,7 @@ class GenUseLocalDesc(object):
os.utime(desc_path, (mtime, mtime))
-class GenChangeLogs(object):
+class GenChangeLogs:
def __init__(self, portdb, changelog_output, changelog_reversed,
max_jobs=None, max_load=None):
self.returncode = os.EX_OK
@@ -709,7 +706,7 @@ class GenChangeLogs(object):
# This cp has not been added to the repo.
return
- lmod = long(lmod)
+ lmod = int(lmod)
try:
cmod = os.stat('ChangeLog')[stat.ST_MTIME]
diff --git a/bin/filter-bash-environment.py b/bin/filter-bash-environment.py
index 06cac7214..7820538ef 100755
--- a/bin/filter-bash-environment.py
+++ b/bin/filter-bash-environment.py
@@ -136,14 +136,9 @@ if __name__ == "__main__":
sys.stderr.flush()
sys.exit(2)
- file_in = sys.stdin
- file_out = sys.stdout
- if sys.hexversion >= 0x3000000:
- file_in = sys.stdin.buffer
- file_out = sys.stdout.buffer
- var_pattern = os.fsencode(args[0]).split()
- else:
- var_pattern = args[0].split()
+ file_in = sys.stdin.buffer
+ file_out = sys.stdout.buffer
+ var_pattern = os.fsencode(args[0]).split()
# Filter invalid variable names that are not supported by bash.
var_pattern.append(br'\d.*')
diff --git a/bin/glsa-check b/bin/glsa-check
index f9dae110f..64a4ea617 100755
--- a/bin/glsa-check
+++ b/bin/glsa-check
@@ -2,7 +2,7 @@
# Copyright 1999-2019 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
import argparse
import re
diff --git a/bin/install.py b/bin/install.py
index 03a4511bb..2dc0ccc4c 100755
--- a/bin/install.py
+++ b/bin/install.py
@@ -232,16 +232,15 @@ def main(args):
cmdline = [install_binary]
cmdline += args
- if sys.hexversion >= 0x3000000:
- # We can't trust that the filesystem encoding (locale dependent)
- # correctly matches the arguments, so use surrogateescape to
- # pass through the original argv bytes for Python 3.
- fs_encoding = sys.getfilesystemencoding()
- cmdline = [x.encode(fs_encoding, 'surrogateescape') for x in cmdline]
- files = [x.encode(fs_encoding, 'surrogateescape') for x in files]
- if opts.target_directory is not None:
- opts.target_directory = \
- opts.target_directory.encode(fs_encoding, 'surrogateescape')
+ # We can't trust that the filesystem encoding (locale dependent)
+ # correctly matches the arguments, so use surrogateescape to
+ # pass through the original argv bytes for Python 3.
+ fs_encoding = sys.getfilesystemencoding()
+ cmdline = [x.encode(fs_encoding, 'surrogateescape') for x in cmdline]
+ files = [x.encode(fs_encoding, 'surrogateescape') for x in files]
+ if opts.target_directory is not None:
+ opts.target_directory = \
+ opts.target_directory.encode(fs_encoding, 'surrogateescape')
returncode = subprocess.call(cmdline)
if returncode == os.EX_OK:
diff --git a/bin/pid-ns-init b/bin/pid-ns-init
index 18c74f799..3a218a5df 100644
--- a/bin/pid-ns-init
+++ b/bin/pid-ns-init
@@ -39,7 +39,7 @@ def preexec_fn(uid, gid, groups, umask):
os.umask(umask)
# CPython >= 3 subprocess.Popen handles this internally.
- if sys.version_info.major < 3 or platform.python_implementation() != 'CPython':
+ if platform.python_implementation() != 'CPython':
for signum in (
signal.SIGHUP,
signal.SIGINT,
@@ -70,10 +70,10 @@ def main(argv):
groups = tuple(int(group) for group in groups.split(',')) if groups else None
umask = int(umask) if umask else None
- popen_kwargs = {}
- popen_kwargs['preexec_fn'] = functools.partial(preexec_fn, uid, gid, groups, umask)
- if sys.version_info.major > 2:
- popen_kwargs['pass_fds'] = pass_fds
+ popen_kwargs = {
+ 'preexec_fn': functools.partial(preexec_fn, uid, gid, groups, umask),
+ 'pass_fds': pass_fds,
+ }
# Isolate parent process from process group SIGSTOP (bug 675870)
setsid = True
os.setsid()
diff --git a/bin/portageq b/bin/portageq
index 2d572b70c..d54f8d02b 100755
--- a/bin/portageq
+++ b/bin/portageq
@@ -2,7 +2,7 @@
# Copyright 1999-2018 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
import argparse
import signal
@@ -1020,7 +1020,7 @@ docstrings['list_preserved_libs'] = """<eroot>
list_preserved_libs.__doc__ = docstrings['list_preserved_libs']
-class MaintainerEmailMatcher(object):
+class MaintainerEmailMatcher:
def __init__(self, maintainer_emails):
self._re = re.compile("^(%s)$" % "|".join(maintainer_emails), re.I)
diff --git a/bin/quickpkg b/bin/quickpkg
index b9ce52f8a..17de837f7 100755
--- a/bin/quickpkg
+++ b/bin/quickpkg
@@ -137,7 +137,7 @@ def quickpkg_atom(options, infos, arg, eout):
missing_package = compression["package"]
eout.eerror("File compression unsupported %s. Missing package: %s" % (binpkg_compression, missing_package))
return 1
- cmd = [varexpand(x, mydict=settings) for x in shlex_split(compression["compress"])]
+ cmd = shlex_split(varexpand(compression["compress"], mydict=settings))
# Filter empty elements that make Popen fail
cmd = [x for x in cmd if x != ""]
with open(binpkg_tmpfile, "wb") as fobj:
diff --git a/bin/socks5-server.py b/bin/socks5-server.py
index 1d07c98ed..8a1a4d1be 100644
--- a/bin/socks5-server.py
+++ b/bin/socks5-server.py
@@ -24,7 +24,7 @@ except AttributeError:
current_task = asyncio.Task.current_task
-class Socks5Server(object):
+class Socks5Server:
"""
An asynchronous SOCKSv5 server.
"""
diff --git a/bin/xattr-helper.py b/bin/xattr-helper.py
index a8aef3880..7ece98027 100755
--- a/bin/xattr-helper.py
+++ b/bin/xattr-helper.py
@@ -26,24 +26,14 @@ _UNQUOTE_RE = re.compile(br'\\[0-7]{3}')
_FS_ENCODING = sys.getfilesystemencoding()
-if sys.hexversion < 0x3000000:
+def octal_quote_byte(b):
+ return ('\\%03o' % ord(b)).encode('ascii')
- def octal_quote_byte(b):
- return b'\\%03o' % ord(b)
- def unicode_encode(s):
- if isinstance(s, unicode):
- s = s.encode(_FS_ENCODING)
- return s
-else:
-
- def octal_quote_byte(b):
- return ('\\%03o' % ord(b)).encode('ascii')
-
- def unicode_encode(s):
- if isinstance(s, str):
- s = s.encode(_FS_ENCODING, 'surrogateescape')
- return s
+def unicode_encode(s):
+ if isinstance(s, str):
+ s = s.encode(_FS_ENCODING, 'surrogateescape')
+ return s
def quote(s, quote_chars):
@@ -157,20 +147,14 @@ def main(argv):
options = parser.parse_args(argv)
- if sys.hexversion >= 0x3000000:
- file_in = sys.stdin.buffer.raw
- else:
- file_in = sys.stdin
+ file_in = sys.stdin.buffer.raw
if options.dump:
if options.paths:
options.paths = [unicode_encode(x) for x in options.paths]
else:
options.paths = [x for x in file_in.read().split(b'\0') if x]
- if sys.hexversion >= 0x3000000:
- file_out = sys.stdout.buffer
- else:
- file_out = sys.stdout
+ file_out = sys.stdout.buffer
dump_xattrs(options.paths, file_out)
elif options.restore:
diff --git a/lib/_emerge/AbstractEbuildProcess.py b/lib/_emerge/AbstractEbuildProcess.py
index 1c1955cfe..ae1aae55f 100644
--- a/lib/_emerge/AbstractEbuildProcess.py
+++ b/lib/_emerge/AbstractEbuildProcess.py
@@ -1,4 +1,4 @@
-# Copyright 1999-2019 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import errno
@@ -196,6 +196,7 @@ class AbstractEbuildProcess(SpawnProcess):
null_fd = os.open('/dev/null', os.O_RDONLY)
self.fd_pipes[0] = null_fd
+ self.log_filter_file = self.settings.get('PORTAGE_LOG_FILTER_FILE_CMD')
try:
SpawnProcess._start(self)
finally:
diff --git a/lib/_emerge/AbstractPollTask.py b/lib/_emerge/AbstractPollTask.py
index 7e9f2b536..661b81616 100644
--- a/lib/_emerge/AbstractPollTask.py
+++ b/lib/_emerge/AbstractPollTask.py
@@ -3,7 +3,6 @@
import array
import errno
-import logging
import os
from portage.util import writemsg_level
diff --git a/lib/_emerge/AsynchronousLock.py b/lib/_emerge/AsynchronousLock.py
index aed1bcb15..d2a6773ff 100644
--- a/lib/_emerge/AsynchronousLock.py
+++ b/lib/_emerge/AsynchronousLock.py
@@ -1,4 +1,4 @@
-# Copyright 2010-2018 Gentoo Foundation
+# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import fcntl
@@ -192,16 +192,6 @@ class _LockProcess(AbstractPollTask):
fcntl.fcntl(in_pr, fcntl.F_SETFL,
fcntl.fcntl(in_pr, fcntl.F_GETFL) | os.O_NONBLOCK)
- # FD_CLOEXEC is enabled by default in Python >=3.4.
- if sys.hexversion < 0x3040000:
- try:
- fcntl.FD_CLOEXEC
- except AttributeError:
- pass
- else:
- fcntl.fcntl(in_pr, fcntl.F_SETFD,
- fcntl.fcntl(in_pr, fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
-
self.scheduler.add_reader(in_pr, self._output_handler)
self._registered = True
self._proc = SpawnProcess(
diff --git a/lib/_emerge/BinpkgFetcher.py b/lib/_emerge/BinpkgFetcher.py
index 36d027de3..218d4d2ab 100644
--- a/lib/_emerge/BinpkgFetcher.py
+++ b/lib/_emerge/BinpkgFetcher.py
@@ -1,4 +1,4 @@
-# Copyright 1999-2018 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import functools
@@ -6,10 +6,7 @@ import functools
from _emerge.AsynchronousLock import AsynchronousLock
from _emerge.CompositeTask import CompositeTask
from _emerge.SpawnProcess import SpawnProcess
-try:
- from urllib.parse import urlparse as urllib_parse_urlparse
-except ImportError:
- from urlparse import urlparse as urllib_parse_urlparse
+from urllib.parse import urlparse as urllib_parse_urlparse
import stat
import sys
import portage
@@ -17,9 +14,6 @@ from portage import os
from portage.util._async.AsyncTaskFuture import AsyncTaskFuture
from portage.util._pty import _create_pty_or_pipe
-if sys.hexversion >= 0x3000000:
- long = int
-
class BinpkgFetcher(CompositeTask):
@@ -158,6 +152,7 @@ class _BinpkgFetcherProcess(SpawnProcess):
self.env = fetch_env
if settings.selinux_enabled():
self._selinux_type = settings["PORTAGE_FETCH_T"]
+ self.log_filter_file = settings.get('PORTAGE_LOG_FILTER_FILE_CMD')
SpawnProcess._start(self)
def _pipe(self, fd_pipes):
@@ -184,7 +179,7 @@ class _BinpkgFetcherProcess(SpawnProcess):
self.pkg.cpv)].get("_mtime_")
if remote_mtime is not None:
try:
- remote_mtime = long(remote_mtime)
+ remote_mtime = int(remote_mtime)
except ValueError:
pass
else:
@@ -237,4 +232,3 @@ class _BinpkgFetcherProcess(SpawnProcess):
self._lock_obj = None
self.locked = False
return result
-
diff --git a/lib/_emerge/BinpkgPrefetcher.py b/lib/_emerge/BinpkgPrefetcher.py
index 7ca897049..1393297b5 100644
--- a/lib/_emerge/BinpkgPrefetcher.py
+++ b/lib/_emerge/BinpkgPrefetcher.py
@@ -40,4 +40,3 @@ class BinpkgPrefetcher(CompositeTask):
self._current_task = None
self.returncode = os.EX_OK
self.wait()
-
diff --git a/lib/_emerge/BlockerCache.py b/lib/_emerge/BlockerCache.py
index 53342d6d6..8154d9ade 100644
--- a/lib/_emerge/BlockerCache.py
+++ b/lib/_emerge/BlockerCache.py
@@ -1,24 +1,12 @@
-# Copyright 1999-2013 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import errno
-import sys
from portage.util import writemsg
from portage.data import secpass
import portage
from portage import os
-
-try:
- import cPickle as pickle
-except ImportError:
- import pickle
-
-if sys.hexversion >= 0x3000000:
- basestring = str
- long = int
- _unicode = str
-else:
- _unicode = unicode
+import pickle
class BlockerCache(portage.cache.mappings.MutableMapping):
"""This caches blockers of installed packages so that dep_check does not
@@ -32,7 +20,7 @@ class BlockerCache(portage.cache.mappings.MutableMapping):
# it's wasteful to update it for every vdb change.
_cache_threshold = 5
- class BlockerData(object):
+ class BlockerData:
__slots__ = ("__weakref__", "atoms", "counter")
@@ -82,7 +70,7 @@ class BlockerCache(portage.cache.mappings.MutableMapping):
# corruption is detected as soon as possible.
invalid_items = set()
for k, v in self._cache_data["blockers"].items():
- if not isinstance(k, basestring):
+ if not isinstance(k, str):
invalid_items.add(k)
continue
try:
@@ -97,7 +85,7 @@ class BlockerCache(portage.cache.mappings.MutableMapping):
invalid_items.add(k)
continue
counter, atoms = v
- if not isinstance(counter, (int, long)):
+ if not isinstance(counter, int):
invalid_items.add(k)
continue
if not isinstance(atoms, (list, tuple)):
@@ -105,7 +93,7 @@ class BlockerCache(portage.cache.mappings.MutableMapping):
continue
invalid_atom = False
for atom in atoms:
- if not isinstance(atom, basestring):
+ if not isinstance(atom, str):
invalid_atom = True
break
if atom[:1] != "!" or \
@@ -164,8 +152,8 @@ class BlockerCache(portage.cache.mappings.MutableMapping):
@param blocker_data: An object with counter and atoms attributes.
@type blocker_data: BlockerData
"""
- self._cache_data["blockers"][_unicode(cpv)] = (blocker_data.counter,
- tuple(_unicode(x) for x in blocker_data.atoms))
+ self._cache_data["blockers"][str(cpv)] = (blocker_data.counter,
+ tuple(str(x) for x in blocker_data.atoms))
self._modified.add(cpv)
def __iter__(self):
@@ -188,4 +176,3 @@ class BlockerCache(portage.cache.mappings.MutableMapping):
@return: An object with counter and atoms attributes.
"""
return self.BlockerData(*self._cache_data["blockers"][cpv])
-
diff --git a/lib/_emerge/BlockerDB.py b/lib/_emerge/BlockerDB.py
index 5b3b01c37..7e1f88615 100644
--- a/lib/_emerge/BlockerDB.py
+++ b/lib/_emerge/BlockerDB.py
@@ -1,7 +1,6 @@
-# Copyright 1999-2018 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-import sys
import portage
from portage import os
@@ -13,10 +12,8 @@ from _emerge.BlockerCache import BlockerCache
from _emerge.Package import Package
from _emerge.show_invalid_depstring_notice import show_invalid_depstring_notice
-if sys.hexversion >= 0x3000000:
- long = int
-class BlockerDB(object):
+class BlockerDB:
def __init__(self, fake_vartree):
root_config = fake_vartree._root_config
diff --git a/lib/_emerge/DepPriority.py b/lib/_emerge/DepPriority.py
index 34fdb481c..ec79bb3d5 100644
--- a/lib/_emerge/DepPriority.py
+++ b/lib/_emerge/DepPriority.py
@@ -53,4 +53,3 @@ class DepPriority(AbstractDepPriority):
if self.runtime_post:
return "runtime_post"
return "soft"
-
diff --git a/lib/_emerge/DepPriorityNormalRange.py b/lib/_emerge/DepPriorityNormalRange.py
index 86395549f..5f3f3da70 100644
--- a/lib/_emerge/DepPriorityNormalRange.py
+++ b/lib/_emerge/DepPriorityNormalRange.py
@@ -2,7 +2,7 @@
# Distributed under the terms of the GNU General Public License v2
from _emerge.DepPriority import DepPriority
-class DepPriorityNormalRange(object):
+class DepPriorityNormalRange:
"""
DepPriority properties Index Category
diff --git a/lib/_emerge/DepPrioritySatisfiedRange.py b/lib/_emerge/DepPrioritySatisfiedRange.py
index 391f5409b..e056e676f 100644
--- a/lib/_emerge/DepPrioritySatisfiedRange.py
+++ b/lib/_emerge/DepPrioritySatisfiedRange.py
@@ -2,7 +2,7 @@
# Distributed under the terms of the GNU General Public License v2
from _emerge.DepPriority import DepPriority
-class DepPrioritySatisfiedRange(object):
+class DepPrioritySatisfiedRange:
"""
DepPriority Index Category
diff --git a/lib/_emerge/Dependency.py b/lib/_emerge/Dependency.py
index 2ec860f83..ab3c5bbff 100644
--- a/lib/_emerge/Dependency.py
+++ b/lib/_emerge/Dependency.py
@@ -18,4 +18,3 @@ class Dependency(SlotObject):
self.collapsed_parent = self.parent
if self.collapsed_priority is None:
self.collapsed_priority = self.priority
-
diff --git a/lib/_emerge/DependencyArg.py b/lib/_emerge/DependencyArg.py
index 29a0072c4..f7ac879ec 100644
--- a/lib/_emerge/DependencyArg.py
+++ b/lib/_emerge/DependencyArg.py
@@ -1,13 +1,10 @@
-# Copyright 1999-2013 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
-import sys
from portage import _encodings, _unicode_encode
-class DependencyArg(object):
+class DependencyArg:
__slots__ = ('arg', 'force_reinstall', 'internal', 'reset_depth', 'root_config')
@@ -33,14 +30,4 @@ class DependencyArg(object):
return hash((self.arg, self.root_config.root))
def __str__(self):
- # Use unicode_literals format string for python-2.x safety,
- # ensuring that self.arg.__unicode__() is used
- # when necessary.
return "%s" % (self.arg,)
-
- if sys.hexversion < 0x3000000:
-
- __unicode__ = __str__
-
- def __str__(self):
- return _unicode_encode(self.__unicode__(), encoding=_encodings['content'])
diff --git a/lib/_emerge/EbuildBuild.py b/lib/_emerge/EbuildBuild.py
index ab5a4da74..4da815988 100644
--- a/lib/_emerge/EbuildBuild.py
+++ b/lib/_emerge/EbuildBuild.py
@@ -1,8 +1,6 @@
# Copyright 1999-2018 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import functools
import io
@@ -161,18 +159,18 @@ class EbuildBuild(CompositeTask):
settings=self.settings),
self._default_final_exit)
return
- else:
- fetcher = EbuildFetcher(
- config_pool=self.config_pool,
- ebuild_path=self._ebuild_path,
- fetchall=self.opts.fetch_all_uri,
- fetchonly=self.opts.fetchonly,
- background=False,
- logfile=None,
- pkg=self.pkg,
- scheduler=self.scheduler)
- self._start_task(fetcher, self._fetchonly_exit)
- return
+
+ fetcher = EbuildFetcher(
+ config_pool=self.config_pool,
+ ebuild_path=self._ebuild_path,
+ fetchall=self.opts.fetch_all_uri,
+ fetchonly=self.opts.fetchonly,
+ background=False,
+ logfile=None,
+ pkg=self.pkg,
+ scheduler=self.scheduler)
+ self._start_task(fetcher, self._fetchonly_exit)
+ return
self._build_dir = EbuildBuildDir(
scheduler=self.scheduler, settings=settings)
diff --git a/lib/_emerge/EbuildBuildDir.py b/lib/_emerge/EbuildBuildDir.py
index 477113db8..04667dbd7 100644
--- a/lib/_emerge/EbuildBuildDir.py
+++ b/lib/_emerge/EbuildBuildDir.py
@@ -158,4 +158,3 @@ class EbuildBuildDir(SlotObject):
class AlreadyLocked(portage.exception.PortageException):
pass
-
diff --git a/lib/_emerge/EbuildExecuter.py b/lib/_emerge/EbuildExecuter.py
index acc57c1d0..11e49804f 100644
--- a/lib/_emerge/EbuildExecuter.py
+++ b/lib/_emerge/EbuildExecuter.py
@@ -79,4 +79,3 @@ class EbuildExecuter(CompositeTask):
settings=self.settings))
self._start_task(ebuild_phases, self._default_final_exit)
-
diff --git a/lib/_emerge/EbuildFetcher.py b/lib/_emerge/EbuildFetcher.py
index 1e40994fb..107a6d590 100644
--- a/lib/_emerge/EbuildFetcher.py
+++ b/lib/_emerge/EbuildFetcher.py
@@ -1,4 +1,4 @@
-# Copyright 1999-2018 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import copy
@@ -225,6 +225,7 @@ class _EbuildFetcherProcess(ForkProcess):
settings["NOCOLOR"] = nocolor
self._settings = settings
+ self.log_filter_file = settings.get('PORTAGE_LOG_FILTER_FILE_CMD')
ForkProcess._start(self)
# Free settings now since it's no longer needed in
@@ -363,16 +364,11 @@ class _EbuildFetcherProcess(ForkProcess):
if msg:
self.scheduler.output(msg, log_path=self.logfile)
- def _async_waitpid_cb(self, *args, **kwargs):
+ def _proc_join_done(self, proc, future):
"""
- Override _async_waitpid_cb to perform cleanup that is
- not necessarily idempotent.
+ Extend _proc_join_done to emit an eerror message for fetch failure.
"""
- ForkProcess._async_waitpid_cb(self, *args, **kwargs)
- # Collect elog messages that might have been
- # created by the pkg_nofetch phase.
- # Skip elog messages for prefetch, in order to avoid duplicates.
- if not self.prefetch and self.returncode != os.EX_OK:
+ if not self.prefetch and not future.cancelled() and proc.exitcode != os.EX_OK:
msg_lines = []
msg = "Fetch failed for '%s'" % (self.pkg.cpv,)
if self.logfile is not None:
@@ -381,3 +377,4 @@ class _EbuildFetcherProcess(ForkProcess):
if self.logfile is not None:
msg_lines.append(" '%s'" % (self.logfile,))
self._eerror(msg_lines)
+ super(_EbuildFetcherProcess, self)._proc_join_done(proc, future)
diff --git a/lib/_emerge/EbuildMetadataPhase.py b/lib/_emerge/EbuildMetadataPhase.py
index efe71892c..d00f194c2 100644
--- a/lib/_emerge/EbuildMetadataPhase.py
+++ b/lib/_emerge/EbuildMetadataPhase.py
@@ -1,4 +1,4 @@
-# Copyright 1999-2018 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
from _emerge.SubProcess import SubProcess
@@ -93,16 +93,6 @@ class EbuildMetadataPhase(SubProcess):
fcntl.fcntl(master_fd, fcntl.F_SETFL,
fcntl.fcntl(master_fd, fcntl.F_GETFL) | os.O_NONBLOCK)
- # FD_CLOEXEC is enabled by default in Python >=3.4.
- if sys.hexversion < 0x3040000:
- try:
- fcntl.FD_CLOEXEC
- except AttributeError:
- pass
- else:
- fcntl.fcntl(master_fd, fcntl.F_SETFD,
- fcntl.fcntl(master_fd, fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
-
fd_pipes[slave_fd] = slave_fd
settings["PORTAGE_PIPE_FD"] = str(slave_fd)
diff --git a/lib/_emerge/EbuildPhase.py b/lib/_emerge/EbuildPhase.py
index 477e0ba97..e6256d0aa 100644
--- a/lib/_emerge/EbuildPhase.py
+++ b/lib/_emerge/EbuildPhase.py
@@ -1,8 +1,6 @@
# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import functools
import gzip
import io
@@ -26,6 +24,8 @@ from portage.package.ebuild.prepare_build_dirs import (_prepare_workdir,
from portage.util.futures.compat_coroutine import coroutine
from portage.util import writemsg
from portage.util._async.AsyncTaskFuture import AsyncTaskFuture
+from portage.util._async.BuildLogger import BuildLogger
+from portage.util.futures import asyncio
from portage.util.futures.executor.fork import ForkExecutor
try:
@@ -45,7 +45,8 @@ portage.proxy.lazyimport.lazyimport(globals(),
'_post_src_install_soname_symlinks,' + \
'_post_src_install_uid_fix,_postinst_bsdflags,' + \
'_post_src_install_write_metadata,' + \
- '_preinst_bsdflags'
+ '_preinst_bsdflags',
+ 'portage.util.futures.unix_events:_set_nonblocking',
)
from portage import os
from portage import _encodings
@@ -69,6 +70,11 @@ class EbuildPhase(CompositeTask):
_locked_phases = ("setup", "preinst", "postinst", "prerm", "postrm")
def _start(self):
+ future = asyncio.ensure_future(self._async_start(), loop=self.scheduler)
+ self._start_task(AsyncTaskFuture(future=future), self._async_start_exit)
+
+ @coroutine
+ def _async_start(self):
need_builddir = self.phase not in EbuildProcess._phases_without_builddir
@@ -126,7 +132,7 @@ class EbuildPhase(CompositeTask):
# Force background=True for this header since it's intended
# for the log and it doesn't necessarily need to be visible
# elsewhere.
- self._elog('einfo', msg, background=True)
+ yield self._elog('einfo', msg, background=True)
if self.phase == 'package':
if 'PORTAGE_BINPKG_TMPFILE' not in self.settings:
@@ -134,6 +140,12 @@ class EbuildPhase(CompositeTask):
os.path.join(self.settings['PKGDIR'],
self.settings['CATEGORY'], self.settings['PF']) + '.tbz2'
+ def _async_start_exit(self, task):
+ task.future.cancelled() or task.future.result()
+ if self._default_exit(task) != os.EX_OK:
+ self.wait()
+ return
+
if self.phase in ("pretend", "prerm"):
env_extractor = BinpkgEnvExtractor(background=self.background,
scheduler=self.scheduler, settings=self.settings)
@@ -391,6 +403,7 @@ class EbuildPhase(CompositeTask):
self.returncode = 1
self.wait()
+ @coroutine
def _elog(self, elog_funcname, lines, background=None):
if background is None:
background = self.background
@@ -407,11 +420,31 @@ class EbuildPhase(CompositeTask):
portage.output.havecolor = global_havecolor
msg = out.getvalue()
if msg:
- log_path = None
- if self.settings.get("PORTAGE_BACKGROUND") != "subprocess":
- log_path = self.settings.get("PORTAGE_LOG_FILE")
- self.scheduler.output(msg, log_path=log_path,
- background=background)
+ build_logger = None
+ try:
+ log_file = None
+ log_path = None
+ if self.settings.get("PORTAGE_BACKGROUND") != "subprocess":
+ log_path = self.settings.get("PORTAGE_LOG_FILE")
+ if log_path:
+ build_logger = BuildLogger(env=self.settings.environ(),
+ log_path=log_path,
+ log_filter_file=self.settings.get('PORTAGE_LOG_FILTER_FILE_CMD'),
+ scheduler=self.scheduler)
+ build_logger.start()
+ _set_nonblocking(build_logger.stdin.fileno())
+ log_file = build_logger.stdin
+
+ yield self.scheduler.async_output(msg, log_file=log_file,
+ background=background)
+
+ if build_logger is not None:
+ build_logger.stdin.close()
+ yield build_logger.async_wait()
+ except asyncio.CancelledError:
+ if build_logger is not None:
+ build_logger.cancel()
+ raise
class _PostPhaseCommands(CompositeTask):
@@ -480,4 +513,4 @@ class _PostPhaseCommands(CompositeTask):
qa_msg.extend("\t%s: %s" % (filename, " ".join(sorted(soname_deps)))
for filename, soname_deps in unresolved)
qa_msg.append("")
- self.elog("eqawarn", qa_msg)
+ yield self.elog("eqawarn", qa_msg)
diff --git a/lib/_emerge/FakeVartree.py b/lib/_emerge/FakeVartree.py
index 3f82e97e9..37349bcdd 100644
--- a/lib/_emerge/FakeVartree.py
+++ b/lib/_emerge/FakeVartree.py
@@ -1,9 +1,6 @@
-# Copyright 1999-2013 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
-import sys
import warnings
import portage
@@ -19,13 +16,8 @@ from portage.update import grab_updates, parse_updates, update_dbentries
from portage.versions import _pkg_str
from _emerge.resolver.DbapiProvidesIndex import PackageDbapiProvidesIndex
-if sys.hexversion >= 0x3000000:
- long = int
- _unicode = str
-else:
- _unicode = unicode
-class FakeVardbGetPath(object):
+class FakeVardbGetPath:
"""
Implements the vardbapi.getpath() method which is used in error handling
code for the Package class and vartree.get_provide().
@@ -167,7 +159,7 @@ class FakeVartree(vartree):
raise _DynamicDepsNotApplicable()
for k, v in built_slot_operator_atoms.items():
live_metadata[k] += (" " +
- " ".join(_unicode(atom) for atom in v))
+ " ".join(str(atom) for atom in v))
self.dbapi.aux_update(pkg.cpv, live_metadata)
except _DynamicDepsNotApplicable:
@@ -249,7 +241,7 @@ class FakeVartree(vartree):
if pkg is not None:
counter, mtime = real_vardb.aux_get(cpv, validation_keys)
try:
- counter = long(counter)
+ counter = int(counter)
except ValueError:
counter = 0
diff --git a/lib/_emerge/FifoIpcDaemon.py b/lib/_emerge/FifoIpcDaemon.py
index 2ec69d1cb..a21e94db6 100644
--- a/lib/_emerge/FifoIpcDaemon.py
+++ b/lib/_emerge/FifoIpcDaemon.py
@@ -1,13 +1,6 @@
-# Copyright 2010-2018 Gentoo Foundation
+# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-import sys
-
-try:
- import fcntl
-except ImportError:
- # http://bugs.jython.org/issue1074
- fcntl = None
from portage import os
from _emerge.AbstractPollTask import AbstractPollTask
@@ -28,17 +21,6 @@ class FifoIpcDaemon(AbstractPollTask):
self._files.pipe_in = \
os.open(self.input_fifo, os.O_RDONLY|os.O_NONBLOCK)
- # FD_CLOEXEC is enabled by default in Python >=3.4.
- if sys.hexversion < 0x3040000 and fcntl is not None:
- try:
- fcntl.FD_CLOEXEC
- except AttributeError:
- pass
- else:
- fcntl.fcntl(self._files.pipe_in, fcntl.F_SETFD,
- fcntl.fcntl(self._files.pipe_in,
- fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
-
self.scheduler.add_reader(
self._files.pipe_in,
self._input_handler)
@@ -55,17 +37,6 @@ class FifoIpcDaemon(AbstractPollTask):
self._files.pipe_in = \
os.open(self.input_fifo, os.O_RDONLY|os.O_NONBLOCK)
- # FD_CLOEXEC is enabled by default in Python >=3.4.
- if sys.hexversion < 0x3040000 and fcntl is not None:
- try:
- fcntl.FD_CLOEXEC
- except AttributeError:
- pass
- else:
- fcntl.fcntl(self._files.pipe_in, fcntl.F_SETFD,
- fcntl.fcntl(self._files.pipe_in,
- fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
-
self.scheduler.add_reader(
self._files.pipe_in,
self._input_handler)
diff --git a/lib/_emerge/JobStatusDisplay.py b/lib/_emerge/JobStatusDisplay.py
index b8e142af9..8986e90db 100644
--- a/lib/_emerge/JobStatusDisplay.py
+++ b/lib/_emerge/JobStatusDisplay.py
@@ -1,8 +1,6 @@
-# Copyright 1999-2015 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import io
import sys
import time
@@ -16,10 +14,7 @@ from portage.output import xtermTitle
from _emerge.getloadavg import getloadavg
-if sys.hexversion >= 0x3000000:
- basestring = str
-
-class JobStatusDisplay(object):
+class JobStatusDisplay:
_bound_properties = ("curval", "failed", "running")
@@ -61,7 +56,7 @@ class JobStatusDisplay(object):
object.__setattr__(self, "_term_codes", term_codes)
encoding = sys.getdefaultencoding()
for k, v in self._term_codes.items():
- if not isinstance(v, basestring):
+ if not isinstance(v, str):
self._term_codes[k] = v.decode(encoding, 'replace')
if self._isatty:
@@ -88,9 +83,7 @@ class JobStatusDisplay(object):
# avoid potential UnicodeEncodeError
s = _unicode_encode(s,
encoding=_encodings['stdio'], errors='backslashreplace')
- out = self.out
- if sys.hexversion >= 0x3000000:
- out = out.buffer
+ out = self.out.buffer
out.write(s)
out.flush()
diff --git a/lib/_emerge/MergeListItem.py b/lib/_emerge/MergeListItem.py
index 938f8014a..3b65b16a2 100644
--- a/lib/_emerge/MergeListItem.py
+++ b/lib/_emerge/MergeListItem.py
@@ -85,7 +85,7 @@ class MergeListItem(CompositeTask):
self._start_task(build, self._default_final_exit)
return
- elif pkg.type_name == "binary":
+ if pkg.type_name == "binary":
binpkg = Binpkg(background=self.background,
find_blockers=find_blockers,
diff --git a/lib/_emerge/Package.py b/lib/_emerge/Package.py
index b2dfc07c1..1a837cb44 100644
--- a/lib/_emerge/Package.py
+++ b/lib/_emerge/Package.py
@@ -1,10 +1,6 @@
-# Copyright 1999-2018 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
-import functools
-import sys
from itertools import chain
import warnings
@@ -21,13 +17,6 @@ from portage.exception import InvalidData, InvalidDependString
from portage.localization import _
from _emerge.Task import Task
-if sys.hexversion >= 0x3000000:
- basestring = str
- long = int
- _unicode = str
-else:
- _unicode = unicode
-
class Package(Task):
__hash__ = Task.__hash__
@@ -222,7 +211,7 @@ class Package(Task):
else:
raise TypeError("root_config argument is required")
- elements = [type_name, root, _unicode(cpv), operation]
+ elements = [type_name, root, str(cpv), operation]
# For installed (and binary) packages we don't care for the repo
# when it comes to hashing, because there can only be one cpv.
@@ -515,7 +504,7 @@ class Package(Task):
cpv_color = "PKG_NOMERGE"
build_id_str = ""
- if isinstance(self.cpv.build_id, long) and self.cpv.build_id > 0:
+ if isinstance(self.cpv.build_id, int) and self.cpv.build_id > 0:
build_id_str = "-%s" % self.cpv.build_id
s = "(%s, %s" \
@@ -537,15 +526,7 @@ class Package(Task):
s += ")"
return s
- if sys.hexversion < 0x3000000:
-
- __unicode__ = __str__
-
- def __str__(self):
- return _unicode_encode(self.__unicode__(),
- encoding=_encodings['content'])
-
- class _use_class(object):
+ class _use_class:
__slots__ = ("enabled", "_expand", "_expand_hidden",
"_force", "_pkg", "_mask")
@@ -670,7 +651,7 @@ class Package(Task):
return use_str
- class _iuse(object):
+ class _iuse:
__slots__ = ("__weakref__", "_iuse_implicit_match", "_pkg", "alias_mapping",
"all", "all_aliases", "enabled", "disabled", "tokens")
@@ -714,7 +695,7 @@ class Package(Task):
@return: True if all flags are valid USE values which may
be specified in USE dependencies, False otherwise.
"""
- if isinstance(flags, basestring):
+ if isinstance(flags, str):
flags = [flags]
for flag in flags:
@@ -727,7 +708,7 @@ class Package(Task):
"""
@return: A list of flags missing from IUSE.
"""
- if isinstance(flags, basestring):
+ if isinstance(flags, str):
flags = [flags]
missing_iuse = []
for flag in flags:
@@ -743,7 +724,8 @@ class Package(Task):
"""
if flag in self.all:
return flag
- elif flag in self.all_aliases:
+
+ if flag in self.all_aliases:
for k, v in self.alias_mapping.items():
if flag in v:
return k
@@ -873,14 +855,14 @@ class _PackageMetadataWrapper(_PackageMetadataWrapperBase):
getattr(self, "_set_" + k.lower())(k, v)
def _set_inherited(self, k, v):
- if isinstance(v, basestring):
+ if isinstance(v, str):
v = frozenset(v.split())
self._pkg.inherited = v
def _set_counter(self, k, v):
- if isinstance(v, basestring):
+ if isinstance(v, str):
try:
- v = long(v.strip())
+ v = int(v.strip())
except ValueError:
v = 0
self._pkg.counter = v
@@ -898,9 +880,9 @@ class _PackageMetadataWrapper(_PackageMetadataWrapperBase):
pass
def _set__mtime_(self, k, v):
- if isinstance(v, basestring):
+ if isinstance(v, str):
try:
- v = long(v.strip())
+ v = int(v.strip())
except ValueError:
v = 0
self._pkg.mtime = v
diff --git a/lib/_emerge/PackageVirtualDbapi.py b/lib/_emerge/PackageVirtualDbapi.py
index 26293dd98..4bba8c959 100644
--- a/lib/_emerge/PackageVirtualDbapi.py
+++ b/lib/_emerge/PackageVirtualDbapi.py
@@ -1,7 +1,6 @@
-# Copyright 1999-2012 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-import sys
from portage.dbapi import dbapi
from portage.dbapi.dep_expand import dep_expand
@@ -41,9 +40,6 @@ class PackageVirtualDbapi(dbapi):
def __bool__(self):
return bool(self._cpv_map)
- if sys.hexversion < 0x3000000:
- __nonzero__ = __bool__
-
def __iter__(self):
return iter(self._cpv_map.values())
@@ -146,4 +142,3 @@ class PackageVirtualDbapi(dbapi):
def aux_update(self, cpv, values):
self._cpv_map[cpv]._metadata.update(values)
self._clear_cache()
-
diff --git a/lib/_emerge/PipeReader.py b/lib/_emerge/PipeReader.py
index 1aa5ee3bf..852378113 100644
--- a/lib/_emerge/PipeReader.py
+++ b/lib/_emerge/PipeReader.py
@@ -1,8 +1,7 @@
-# Copyright 1999-2018 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import fcntl
-import sys
from portage import os
from _emerge.AbstractPollTask import AbstractPollTask
@@ -27,16 +26,6 @@ class PipeReader(AbstractPollTask):
fcntl.fcntl(fd, fcntl.F_SETFL,
fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)
- # FD_CLOEXEC is enabled by default in Python >=3.4.
- if sys.hexversion < 0x3040000:
- try:
- fcntl.FD_CLOEXEC
- except AttributeError:
- pass
- else:
- fcntl.fcntl(fd, fcntl.F_SETFD,
- fcntl.fcntl(fd, fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
-
if self._use_array:
self.scheduler.add_reader(fd, self._array_output_handler, f)
else:
@@ -103,4 +92,3 @@ class PipeReader(AbstractPollTask):
self.scheduler.remove_reader(f.fileno())
f.close()
self.input_files = None
-
diff --git a/lib/_emerge/PollScheduler.py b/lib/_emerge/PollScheduler.py
index e90830885..f51c5b005 100644
--- a/lib/_emerge/PollScheduler.py
+++ b/lib/_emerge/PollScheduler.py
@@ -14,7 +14,7 @@ from portage.util._eventloop.global_event_loop import global_event_loop
from _emerge.getloadavg import getloadavg
-class PollScheduler(object):
+class PollScheduler:
# max time between loadavg checks (milliseconds)
_loadavg_latency = None
diff --git a/lib/_emerge/ProgressHandler.py b/lib/_emerge/ProgressHandler.py
index f5afe6d87..d7787e040 100644
--- a/lib/_emerge/ProgressHandler.py
+++ b/lib/_emerge/ProgressHandler.py
@@ -2,7 +2,7 @@
# Distributed under the terms of the GNU General Public License v2
import time
-class ProgressHandler(object):
+class ProgressHandler:
def __init__(self):
self.curval = 0
self.maxval = 0
@@ -19,4 +19,3 @@ class ProgressHandler(object):
def display(self):
raise NotImplementedError(self)
-
diff --git a/lib/_emerge/RootConfig.py b/lib/_emerge/RootConfig.py
index 3648d01d7..9dc9636da 100644
--- a/lib/_emerge/RootConfig.py
+++ b/lib/_emerge/RootConfig.py
@@ -1,7 +1,7 @@
# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-class RootConfig(object):
+class RootConfig:
"""This is used internally by depgraph to track information about a
particular $ROOT."""
__slots__ = ("mtimedb", "root", "setconfig", "sets", "settings", "trees")
diff --git a/lib/_emerge/Scheduler.py b/lib/_emerge/Scheduler.py
index 6f4564000..7906c30c8 100644
--- a/lib/_emerge/Scheduler.py
+++ b/lib/_emerge/Scheduler.py
@@ -1,7 +1,7 @@
# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import division, print_function, unicode_literals
+from __future__ import division, print_function
from collections import deque
import gc
@@ -63,9 +63,6 @@ from _emerge.PackageMerge import PackageMerge
from _emerge.PollScheduler import PollScheduler
from _emerge.SequentialTaskQueue import SequentialTaskQueue
-if sys.hexversion >= 0x3000000:
- basestring = str
-
# enums
FAILURE = 1
@@ -123,7 +120,7 @@ class Scheduler(PollScheduler):
__slots__ = ("build_dir", "build_log", "pkg",
"postinst_failure", "returncode")
- class _ConfigPool(object):
+ class _ConfigPool:
"""Interface for a task to temporarily allocate a config
instance from a pool. This allows a task to be constructed
long before the config instance actually becomes needed, like
@@ -1141,7 +1138,7 @@ class Scheduler(PollScheduler):
if phase not in logentries:
continue
for msgtype, msgcontent in logentries[phase]:
- if isinstance(msgcontent, basestring):
+ if isinstance(msgcontent, str):
msgcontent = [msgcontent]
for line in msgcontent:
printer.eerror(line.strip("\n"))
diff --git a/lib/_emerge/SequentialTaskQueue.py b/lib/_emerge/SequentialTaskQueue.py
index d2551b1c6..40590b76c 100644
--- a/lib/_emerge/SequentialTaskQueue.py
+++ b/lib/_emerge/SequentialTaskQueue.py
@@ -2,7 +2,6 @@
# Distributed under the terms of the GNU General Public License v2
from collections import deque
-import sys
from portage.util.futures import asyncio
from portage.util.futures.compat_coroutine import coroutine
@@ -85,8 +84,5 @@ class SequentialTaskQueue(SlotObject):
def __bool__(self):
return bool(self._task_queue or self.running_tasks)
- if sys.hexversion < 0x3000000:
- __nonzero__ = __bool__
-
def __len__(self):
return len(self._task_queue) + len(self.running_tasks)
diff --git a/lib/_emerge/SetArg.py b/lib/_emerge/SetArg.py
index 5c8297547..2fee86c49 100644
--- a/lib/_emerge/SetArg.py
+++ b/lib/_emerge/SetArg.py
@@ -11,4 +11,3 @@ class SetArg(DependencyArg):
DependencyArg.__init__(self, **kwargs)
self.pset = pset
self.name = self.arg[len(SETPREFIX):]
-
diff --git a/lib/_emerge/SpawnProcess.py b/lib/_emerge/SpawnProcess.py
index 395d66bb9..91f5ed1a8 100644
--- a/lib/_emerge/SpawnProcess.py
+++ b/lib/_emerge/SpawnProcess.py
@@ -1,12 +1,6 @@
-# Copyright 2008-2018 Gentoo Foundation
+# Copyright 2008-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-try:
- import fcntl
-except ImportError:
- # http://bugs.jython.org/issue1074
- fcntl = None
-
import errno
import logging
import signal
@@ -19,7 +13,10 @@ from portage.const import BASH_BINARY
from portage.localization import _
from portage.output import EOutput
from portage.util import writemsg_level
+from portage.util._async.BuildLogger import BuildLogger
from portage.util._async.PipeLogger import PipeLogger
+from portage.util.futures import asyncio
+from portage.util.futures.compat_coroutine import coroutine
class SpawnProcess(SubProcess):
@@ -34,8 +31,8 @@ class SpawnProcess(SubProcess):
"path_lookup", "pre_exec", "close_fds", "cgroup",
"unshare_ipc", "unshare_mount", "unshare_pid", "unshare_net")
- __slots__ = ("args",) + \
- _spawn_kwarg_names + ("_pipe_logger", "_selinux_type",)
+ __slots__ = ("args", "log_filter_file") + \
+ _spawn_kwarg_names + ("_main_task", "_selinux_type",)
# Max number of attempts to kill the processes listed in cgroup.procs,
# given that processes may fork before they can be killed.
@@ -126,24 +123,55 @@ class SpawnProcess(SubProcess):
stdout_fd = None
if can_log and not self.background:
stdout_fd = os.dup(fd_pipes_orig[1])
- # FD_CLOEXEC is enabled by default in Python >=3.4.
- if sys.hexversion < 0x3040000 and fcntl is not None:
- try:
- fcntl.FD_CLOEXEC
- except AttributeError:
- pass
- else:
- fcntl.fcntl(stdout_fd, fcntl.F_SETFD,
- fcntl.fcntl(stdout_fd,
- fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
- self._pipe_logger = PipeLogger(background=self.background,
+ build_logger = BuildLogger(env=self.env,
+ log_path=log_file_path,
+ log_filter_file=self.log_filter_file,
+ scheduler=self.scheduler)
+ build_logger.start()
+
+ pipe_logger = PipeLogger(background=self.background,
scheduler=self.scheduler, input_fd=master_fd,
- log_file_path=log_file_path,
+ log_file_path=build_logger.stdin,
stdout_fd=stdout_fd)
- self._pipe_logger.addExitListener(self._pipe_logger_exit)
- self._pipe_logger.start()
+
+ pipe_logger.start()
+
self._registered = True
+ self._main_task = asyncio.ensure_future(self._main(build_logger, pipe_logger), loop=self.scheduler)
+ self._main_task.add_done_callback(self._main_exit)
+
+ @coroutine
+ def _main(self, build_logger, pipe_logger):
+ try:
+ if pipe_logger.poll() is None:
+ yield pipe_logger.async_wait()
+ if build_logger.poll() is None:
+ yield build_logger.async_wait()
+ except asyncio.CancelledError:
+ if pipe_logger.poll() is None:
+ pipe_logger.cancel()
+ if build_logger.poll() is None:
+ build_logger.cancel()
+ raise
+
+ def _main_exit(self, main_task):
+ self._main_task = None
+ try:
+ main_task.result()
+ except asyncio.CancelledError:
+ self.cancel()
+ self._async_waitpid()
+
+ def _async_wait(self):
+ # Allow _main_task to exit normally rather than via cancellation.
+ if self._main_task is None:
+ super(SpawnProcess, self)._async_wait()
+
+ def _async_waitpid(self):
+ # Allow _main_task to exit normally rather than via cancellation.
+ if self._main_task is None:
+ super(SpawnProcess, self)._async_waitpid()
def _can_log(self, slave_fd):
return True
@@ -167,20 +195,17 @@ class SpawnProcess(SubProcess):
return spawn_func(args, **kwargs)
- def _pipe_logger_exit(self, pipe_logger):
- self._pipe_logger = None
- self._async_waitpid()
-
def _unregister(self):
SubProcess._unregister(self)
if self.cgroup is not None:
self._cgroup_cleanup()
self.cgroup = None
- if self._pipe_logger is not None:
- self._pipe_logger.cancel()
- self._pipe_logger = None
+ if self._main_task is not None:
+ self._main_task.done() or self._main_task.cancel()
def _cancel(self):
+ if self._main_task is not None:
+ self._main_task.done() or self._main_task.cancel()
SubProcess._cancel(self)
self._cgroup_cleanup()
diff --git a/lib/_emerge/SubProcess.py b/lib/_emerge/SubProcess.py
index e834cb7d3..f7353926c 100644
--- a/lib/_emerge/SubProcess.py
+++ b/lib/_emerge/SubProcess.py
@@ -48,9 +48,12 @@ class SubProcess(AbstractPollTask):
def _async_waitpid(self):
"""
Wait for exit status of self.pid asynchronously, and then
- set the returncode and notify exit listeners. This is
- prefered over _waitpid_loop, since the synchronous nature
- of _waitpid_loop can cause event loop recursion.
+ set the returncode, and finally notify exit listeners via the
+ _async_wait method. Subclasses may override this method in order
+ to implement an alternative means to retrieve pid exit status,
+ or as a means to delay action until some pending task(s) have
+ completed (such as reading data that the subprocess is supposed
+ to have written to a pipe).
"""
if self.returncode is not None:
self._async_wait()
diff --git a/lib/_emerge/TaskSequence.py b/lib/_emerge/TaskSequence.py
index 1f2ba94c2..8d1b0b859 100644
--- a/lib/_emerge/TaskSequence.py
+++ b/lib/_emerge/TaskSequence.py
@@ -1,7 +1,6 @@
-# Copyright 1999-2014 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-import sys
from collections import deque
from portage import os
@@ -54,8 +53,5 @@ class TaskSequence(CompositeTask):
def __bool__(self):
return bool(self._task_queue)
- if sys.hexversion < 0x3000000:
- __nonzero__ = __bool__
-
def __len__(self):
return len(self._task_queue)
diff --git a/lib/_emerge/UnmergeDepPriority.py b/lib/_emerge/UnmergeDepPriority.py
index ec44a67a1..ed831ed45 100644
--- a/lib/_emerge/UnmergeDepPriority.py
+++ b/lib/_emerge/UnmergeDepPriority.py
@@ -43,4 +43,3 @@ class UnmergeDepPriority(AbstractDepPriority):
if myvalue > self.SOFT:
return "hard"
return "soft"
-
diff --git a/lib/_emerge/UseFlagDisplay.py b/lib/_emerge/UseFlagDisplay.py
index 12820e9d1..9496693c8 100644
--- a/lib/_emerge/UseFlagDisplay.py
+++ b/lib/_emerge/UseFlagDisplay.py
@@ -1,18 +1,15 @@
-# Copyright 1999-2013 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import collections
from itertools import chain
-import sys
from portage import _encodings, _unicode_encode
from portage.output import red
from portage.util import cmp_sort_key
from portage.output import blue
-class UseFlagDisplay(object):
+class UseFlagDisplay:
__slots__ = ('name', 'enabled', 'forced')
@@ -32,14 +29,6 @@ class UseFlagDisplay(object):
s = '(%s)' % s
return s
- if sys.hexversion < 0x3000000:
-
- __unicode__ = __str__
-
- def __str__(self):
- return _unicode_encode(self.__unicode__(),
- encoding=_encodings['content'])
-
def _cmp_combined(a, b):
"""
Sort by name, combining enabled and disabled flags.
diff --git a/lib/_emerge/UserQuery.py b/lib/_emerge/UserQuery.py
index e20bbc6c3..d5273e4ee 100644
--- a/lib/_emerge/UserQuery.py
+++ b/lib/_emerge/UserQuery.py
@@ -1,7 +1,7 @@
-# Copyright 1999-2016 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
import signal
import sys
@@ -10,7 +10,7 @@ from portage import _unicode_decode
from portage.output import bold, create_color_func
-class UserQuery(object):
+class UserQuery:
"""The UserQuery class is used to prompt the user with a set of responses,
as well as accepting and handling the responses."""
@@ -54,17 +54,12 @@ class UserQuery(object):
print(bold(prompt), end=' ')
try:
while True:
- if sys.hexversion >= 0x3000000:
- try:
- response = input("[%s] " %
- "/".join([colours[i](responses[i])
- for i in range(len(responses))]))
- except UnicodeDecodeError as e:
- response = _unicode_decode(e.object).rstrip('\n')
- else:
- response=raw_input("["+"/".join([colours[i](responses[i])
- for i in range(len(responses))])+"] ")
- response = _unicode_decode(response)
+ try:
+ response = input("[%s] " %
+ "/".join([colours[i](responses[i])
+ for i in range(len(responses))]))
+ except UnicodeDecodeError as e:
+ response = _unicode_decode(e.object).rstrip('\n')
if response or not enter_invalid:
for key in responses:
# An empty response will match the
diff --git a/lib/_emerge/_find_deep_system_runtime_deps.py b/lib/_emerge/_find_deep_system_runtime_deps.py
index ca09d83ac..d88296d5f 100644
--- a/lib/_emerge/_find_deep_system_runtime_deps.py
+++ b/lib/_emerge/_find_deep_system_runtime_deps.py
@@ -35,4 +35,3 @@ def _find_deep_system_runtime_deps(graph):
node_stack.append(child)
return deep_system_deps
-
diff --git a/lib/_emerge/actions.py b/lib/_emerge/actions.py
index d8e9d7774..961ecf3d1 100644
--- a/lib/_emerge/actions.py
+++ b/lib/_emerge/actions.py
@@ -1,19 +1,15 @@
# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import division, print_function, unicode_literals
+from __future__ import division, print_function
import collections
import errno
import logging
import operator
import platform
-import pwd
-import random
import re
import signal
-import socket
-import stat
import subprocess
import sys
import tempfile
@@ -31,7 +27,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
'portage.util.locale:check_locale',
'portage.emaint.modules.sync.sync:SyncRepos',
'_emerge.chk_updated_cfg_files:chk_updated_cfg_files',
- '_emerge.help:help@emerge_help',
+ '_emerge.help:emerge_help',
'_emerge.post_emerge:display_news_notification,post_emerge',
'_emerge.stdout_spinner:stdout_spinner',
)
@@ -95,11 +91,6 @@ from _emerge.UnmergeDepPriority import UnmergeDepPriority
from _emerge.UseFlagDisplay import pkg_use_display
from _emerge.UserQuery import UserQuery
-if sys.hexversion >= 0x3000000:
- long = int
- _unicode = str
-else:
- _unicode = unicode
def action_build(emerge_config, trees=DeprecationWarning,
mtimedb=DeprecationWarning, myopts=DeprecationWarning,
@@ -855,7 +846,7 @@ def _calc_depclean(settings, trees, ldpath_mtimes,
protected_set.add("=" + pkg.cpv)
continue
except portage.exception.InvalidDependString as e:
- show_invalid_depstring_notice(pkg, _unicode(e))
+ show_invalid_depstring_notice(pkg, str(e))
del e
protected_set.add("=" + pkg.cpv)
continue
@@ -908,7 +899,7 @@ def _calc_depclean(settings, trees, ldpath_mtimes,
protected_set.add("=" + pkg.cpv)
continue
except portage.exception.InvalidDependString as e:
- show_invalid_depstring_notice(pkg, _unicode(e))
+ show_invalid_depstring_notice(pkg, str(e))
del e
protected_set.add("=" + pkg.cpv)
continue
@@ -925,7 +916,7 @@ def _calc_depclean(settings, trees, ldpath_mtimes,
if excluded_set.findAtomForPackage(pkg):
required_sets['__excluded__'].add("=" + pkg.cpv)
except portage.exception.InvalidDependString as e:
- show_invalid_depstring_notice(pkg, _unicode(e))
+ show_invalid_depstring_notice(pkg, str(e))
del e
required_sets['__excluded__'].add("=" + pkg.cpv)
@@ -990,14 +981,14 @@ def _calc_depclean(settings, trees, ldpath_mtimes,
# visible in the unevaluated form of the atom. In this
# case, we must display the unevaluated atom, so that
# the user can see the conditional USE deps that would
- # otherwise be invisible. Use Atom(_unicode(atom)) to
+ # otherwise be invisible. Use Atom(str(atom)) to
# test for a package where this case would matter. This
# is not necessarily the same as atom.without_use,
- # since Atom(_unicode(atom)) may still contain some
+ # since Atom(str(atom)) may still contain some
# USE dependencies that remain after evaluation of
# conditionals.
if atom.package and atom != atom.unevaluated_atom and \
- vardb.match(Atom(_unicode(atom))):
+ vardb.match(Atom(str(atom))):
msg.append(" %s (%s) pulled in by:" %
(atom.unevaluated_atom, atom))
else:
@@ -1069,7 +1060,7 @@ def _calc_depclean(settings, trees, ldpath_mtimes,
key=operator.attrgetter('package'))
parent_strs.append("%s requires %s" %
(getattr(parent, "cpv", parent),
- ", ".join(_unicode(atom) for atom in atoms)))
+ ", ".join(str(atom) for atom in atoms)))
parent_strs.sort()
msg = []
msg.append(" %s pulled in by:\n" % (child_node.cpv,))
@@ -1082,10 +1073,9 @@ def _calc_depclean(settings, trees, ldpath_mtimes,
"""Sort Package instances by cpv."""
if pkg1.cpv > pkg2.cpv:
return 1
- elif pkg1.cpv == pkg2.cpv:
+ if pkg1.cpv == pkg2.cpv:
return 0
- else:
- return -1
+ return -1
def create_cleanlist():
@@ -1542,7 +1532,7 @@ def action_deselect(settings, trees, opts, atoms):
writemsg_stdout(
">>> %s %s from \"%s\" favorites file...\n" %
- (action_desc, colorize("INFORM", _unicode(atom)),
+ (action_desc, colorize("INFORM", str(atom)),
filename), noiselevel=-1)
if '--ask' in opts:
@@ -1563,7 +1553,7 @@ def action_deselect(settings, trees, opts, atoms):
world_set.unlock()
return os.EX_OK
-class _info_pkgs_ver(object):
+class _info_pkgs_ver:
def __init__(self, ver, repo_suffix, provide_suffix):
self.ver = ver
self.repo_suffix = repo_suffix
@@ -3031,7 +3021,7 @@ def run_action(emerge_config):
emerge_config.target_config.trees['vartree'].dbapi) + '\n',
noiselevel=-1)
return 0
- elif emerge_config.action == 'help':
+ if emerge_config.action == 'help':
emerge_help()
return 0
@@ -3065,7 +3055,7 @@ def run_action(emerge_config):
writemsg_stdout("".join("%s\n" % s for s in
sorted(emerge_config.target_config.sets)))
return os.EX_OK
- elif emerge_config.action == "check-news":
+ if emerge_config.action == "check-news":
news_counts = count_unread_news(
emerge_config.target_config.trees["porttree"].dbapi,
emerge_config.target_config.trees["vartree"].dbapi)
@@ -3237,8 +3227,6 @@ def run_action(emerge_config):
if not "--pretend" in emerge_config.opts:
time_fmt = "%b %d, %Y %H:%M:%S"
- if sys.hexversion < 0x3000000:
- time_fmt = portage._unicode_encode(time_fmt)
time_str = time.strftime(time_fmt, time.localtime(time.time()))
# Avoid potential UnicodeDecodeError in Python 2, since strftime
# returns bytes in Python 2, and %b may contain non-ascii chars.
@@ -3290,7 +3278,7 @@ def run_action(emerge_config):
if "sync" == emerge_config.action:
return action_sync(emerge_config)
- elif "metadata" == emerge_config.action:
+ if "metadata" == emerge_config.action:
action_metadata(emerge_config.target_config.settings,
emerge_config.target_config.trees['porttree'].dbapi,
emerge_config.opts)
diff --git a/lib/_emerge/create_depgraph_params.py b/lib/_emerge/create_depgraph_params.py
index 81edcb9c0..0d0e07b9c 100644
--- a/lib/_emerge/create_depgraph_params.py
+++ b/lib/_emerge/create_depgraph_params.py
@@ -195,4 +195,3 @@ def create_depgraph_params(myopts, myaction):
noiselevel=-1, level=logging.DEBUG)
return myparams
-
diff --git a/lib/_emerge/create_world_atom.py b/lib/_emerge/create_world_atom.py
index a7f3e30bf..8b506c36e 100644
--- a/lib/_emerge/create_world_atom.py
+++ b/lib/_emerge/create_world_atom.py
@@ -1,15 +1,10 @@
# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-import sys
from portage.dep import Atom, _repo_separator
from portage.exception import InvalidData
-if sys.hexversion >= 0x3000000:
- _unicode = str
-else:
- _unicode = unicode
def create_world_atom(pkg, args_set, root_config, before_install=False):
"""Create a new atom for the world file if one does not exist. If the
@@ -43,7 +38,7 @@ def create_world_atom(pkg, args_set, root_config, before_install=False):
for cpv in portdb.match(Atom(cp)):
for repo in repos:
try:
- available_slots.add(portdb._pkg_str(_unicode(cpv), repo).slot)
+ available_slots.add(portdb._pkg_str(str(cpv), repo).slot)
except (KeyError, InvalidData):
pass
@@ -98,7 +93,7 @@ def create_world_atom(pkg, args_set, root_config, before_install=False):
for repo in repos:
try:
matched_slots.add(
- portdb._pkg_str(_unicode(cpv), repo).slot)
+ portdb._pkg_str(str(cpv), repo).slot)
except (KeyError, InvalidData):
pass
@@ -126,4 +121,3 @@ def create_world_atom(pkg, args_set, root_config, before_install=False):
providers[0].cp == arg_atom.cp:
return None
return new_world_atom
-
diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py
index 13c2b658f..d2406aeec 100644
--- a/lib/_emerge/depgraph.py
+++ b/lib/_emerge/depgraph.py
@@ -1,7 +1,7 @@
# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import division, print_function, unicode_literals
+from __future__ import division, print_function
import collections
import errno
@@ -9,7 +9,6 @@ import functools
import io
import logging
import stat
-import sys
import textwrap
import warnings
from collections import deque, OrderedDict
@@ -88,13 +87,6 @@ from _emerge.resolver.slot_collision import slot_conflict_handler
from _emerge.resolver.circular_dependency import circular_dependency_handler
from _emerge.resolver.output import Display, format_unmatched_atom
-if sys.hexversion >= 0x3000000:
- basestring = str
- long = int
- _unicode = str
-else:
- _unicode = unicode
-
# Exposes a depgraph interface to dep_check.
_dep_check_graph_interface = collections.namedtuple('_dep_check_graph_interface',(
# Indicates a removal action, like depclean or prune.
@@ -103,7 +95,7 @@ _dep_check_graph_interface = collections.namedtuple('_dep_check_graph_interface'
'want_update_pkg',
))
-class _scheduler_graph_config(object):
+class _scheduler_graph_config:
def __init__(self, trees, pkg_cache, graph, mergelist):
self.trees = trees
self.pkg_cache = pkg_cache
@@ -120,7 +112,7 @@ def _wildcard_set(atoms):
pkgs.add(x)
return pkgs
-class _frozen_depgraph_config(object):
+class _frozen_depgraph_config:
def __init__(self, settings, trees, myopts, params, spinner):
self.settings = settings
@@ -194,7 +186,7 @@ class _frozen_depgraph_config(object):
self.rebuild_if_new_ver = "--rebuild-if-new-ver" in myopts
self.rebuild_if_unbuilt = "--rebuild-if-unbuilt" in myopts
-class _depgraph_sets(object):
+class _depgraph_sets:
def __init__(self):
# contains all sets added to the graph
self.sets = {}
@@ -205,7 +197,7 @@ class _depgraph_sets(object):
self.atoms = InternalPackageSet(allow_repo=True)
self.atom_arg_map = {}
-class _rebuild_config(object):
+class _rebuild_config:
def __init__(self, frozen_config, backtrack_parameters):
self._graph = digraph()
self._frozen_config = frozen_config
@@ -270,7 +262,7 @@ class _rebuild_config(object):
if self._needs_rebuild(dep_pkg):
self.rebuild_list.add(root_slot)
return True
- elif ("--usepkg" in self._frozen_config.myopts and
+ if ("--usepkg" in self._frozen_config.myopts and
(dep_root_slot in self.reinstall_list or
dep_root_slot in self.rebuild_list or
not dep_pkg.installed)):
@@ -304,14 +296,14 @@ class _rebuild_config(object):
# built without dep_pkg. Force rebuild.
self.rebuild_list.add(root_slot)
return True
- elif (parent.installed and
+ if (parent.installed and
root_slot not in self.reinstall_list):
try:
bin_build_time, = bindb.aux_get(parent.cpv,
["BUILD_TIME"])
except KeyError:
continue
- if bin_build_time != _unicode(parent.build_time):
+ if bin_build_time != str(parent.build_time):
# 2) Remote binary package is valid, and local package
# is not up to date. Force reinstall.
reinstall = True
@@ -374,7 +366,7 @@ class _use_changes(tuple):
return obj
-class _dynamic_depgraph_config(object):
+class _dynamic_depgraph_config:
"""
``dynamic_depgraph_config`` is an object that is used to collect settings and important data structures that are
@@ -598,7 +590,7 @@ class _dynamic_depgraph_config(object):
dbs.append((vardb, "installed", True, True, db_keys))
self._filtered_trees[myroot]["dbs"] = dbs
-class depgraph(object):
+class depgraph:
# Represents the depth of a node that is unreachable from explicit
# user arguments (or their deep dependencies). Such nodes are pulled
@@ -710,7 +702,7 @@ class depgraph(object):
self._dynamic_deps_proc_exit(pkg, fake_vartree))
yield proc
- class _dynamic_deps_proc_exit(object):
+ class _dynamic_deps_proc_exit:
__slots__ = ('_pkg', '_fake_vartree')
@@ -2574,14 +2566,14 @@ class depgraph(object):
Atom("=%s" % inst_pkg.cpv)):
if not pkg.built:
return pkg.slot_atom
- elif not pkg.installed:
+ if not pkg.installed:
# avoid using SLOT from a built instance
built_pkgs.append(pkg)
for pkg in self._iter_similar_available(inst_pkg, inst_pkg.slot_atom):
if not pkg.built:
return pkg.slot_atom
- elif not pkg.installed:
+ if not pkg.installed:
# avoid using SLOT from a built instance
built_pkgs.append(pkg)
@@ -2907,58 +2899,58 @@ class depgraph(object):
self._slot_operator_unsatisfied_probe(dep)):
self._slot_operator_unsatisfied_backtrack(dep)
return 1
- else:
- # This is for backward-compatibility with previous
- # behavior, so that installed packages with unsatisfied
- # dependencies trigger an error message but do not
- # cause the dependency calculation to fail. Only do
- # this if the parent is already in the runtime package
- # mask, since otherwise we need to backtrack.
- if (dep.parent.installed and
- dep.parent in self._dynamic_config._runtime_pkg_mask and
- not any(self._iter_match_pkgs_any(
- dep.parent.root_config, dep.atom))):
- self._dynamic_config._initially_unsatisfied_deps.append(dep)
- return 1
-
- # Do not backtrack if only USE have to be changed in
- # order to satisfy the dependency. Note that when
- # want_restart_for_use_change sets the need_restart
- # flag, it causes _select_pkg_highest_available to
- # return None, and eventually we come through here
- # and skip the "missing dependency" backtracking path.
- dep_pkg, existing_node = \
- self._select_package(dep.root,
- dep.atom.without_use if dep.atom.package
- else dep.atom, onlydeps=dep.onlydeps)
- if dep_pkg is None:
-
- # In order to suppress the sort of aggressive
- # backtracking that can trigger undesirable downgrades
- # as in bug 693836, do not backtrack if there's an
- # available package which was involved in a slot
- # conflict and satisfied all involved parent atoms.
- for dep_pkg, reasons in self._dynamic_config._runtime_pkg_mask.items():
- if (dep.atom.match(dep_pkg) and
- len(reasons) == 1 and
- not reasons.get("slot conflict", True)):
- self._dynamic_config._skip_restart = True
- return 0
- self._dynamic_config._backtrack_infos["missing dependency"] = dep
- self._dynamic_config._need_restart = True
- if debug:
- msg = []
- msg.append("")
- msg.append("")
- msg.append("backtracking due to unsatisfied dep:")
- msg.append(" parent: %s" % dep.parent)
- msg.append(" priority: %s" % dep.priority)
- msg.append(" root: %s" % dep.root)
- msg.append(" atom: %s" % dep.atom)
- msg.append("")
- writemsg_level("".join("%s\n" % l for l in msg),
- noiselevel=-1, level=logging.DEBUG)
+ # This is for backward-compatibility with previous
+ # behavior, so that installed packages with unsatisfied
+ # dependencies trigger an error message but do not
+ # cause the dependency calculation to fail. Only do
+ # this if the parent is already in the runtime package
+ # mask, since otherwise we need to backtrack.
+ if (dep.parent.installed and
+ dep.parent in self._dynamic_config._runtime_pkg_mask and
+ not any(self._iter_match_pkgs_any(
+ dep.parent.root_config, dep.atom))):
+ self._dynamic_config._initially_unsatisfied_deps.append(dep)
+ return 1
+
+ # Do not backtrack if only USE have to be changed in
+ # order to satisfy the dependency. Note that when
+ # want_restart_for_use_change sets the need_restart
+ # flag, it causes _select_pkg_highest_available to
+ # return None, and eventually we come through here
+ # and skip the "missing dependency" backtracking path.
+ dep_pkg, existing_node = \
+ self._select_package(dep.root,
+ dep.atom.without_use if dep.atom.package
+ else dep.atom, onlydeps=dep.onlydeps)
+ if dep_pkg is None:
+
+ # In order to suppress the sort of aggressive
+ # backtracking that can trigger undesirable downgrades
+ # as in bug 693836, do not backtrack if there's an
+ # available package which was involved in a slot
+ # conflict and satisfied all involved parent atoms.
+ for dep_pkg, reasons in self._dynamic_config._runtime_pkg_mask.items():
+ if (dep.atom.match(dep_pkg) and
+ len(reasons) == 1 and
+ not reasons.get("slot conflict", True)):
+ self._dynamic_config._skip_restart = True
+ return 0
+
+ self._dynamic_config._backtrack_infos["missing dependency"] = dep
+ self._dynamic_config._need_restart = True
+ if debug:
+ msg = []
+ msg.append("")
+ msg.append("")
+ msg.append("backtracking due to unsatisfied dep:")
+ msg.append(" parent: %s" % dep.parent)
+ msg.append(" priority: %s" % dep.priority)
+ msg.append(" root: %s" % dep.root)
+ msg.append(" atom: %s" % dep.atom)
+ msg.append("")
+ writemsg_level("".join("%s\n" % l for l in msg),
+ noiselevel=-1, level=logging.DEBUG)
return 0
@@ -3198,7 +3190,7 @@ class depgraph(object):
dep_stack = self._dynamic_config._dep_stack
if "recurse" not in self._dynamic_config.myparams:
return 1
- elif pkg.installed and not recurse:
+ if pkg.installed and not recurse:
dep_stack = self._dynamic_config._ignored_deps
self._spinner_update()
@@ -5664,9 +5656,8 @@ class depgraph(object):
if atom.package:
return self._iter_match_pkgs_atom(root_config, pkg_type,
atom, onlydeps=onlydeps)
- else:
- return self._iter_match_pkgs_soname(root_config, pkg_type,
- atom, onlydeps=onlydeps)
+ return self._iter_match_pkgs_soname(root_config, pkg_type,
+ atom, onlydeps=onlydeps)
def _iter_match_pkgs_soname(self, root_config, pkg_type, atom,
onlydeps=False):
@@ -5761,7 +5752,7 @@ class depgraph(object):
other_installed, other_keys in dbs:
try:
if portage.dep._match_slot(atom,
- other_db._pkg_str(_unicode(cpv), None)):
+ other_db._pkg_str(str(cpv), None)):
slot_available = True
break
except (KeyError, InvalidData):
@@ -5881,12 +5872,11 @@ class depgraph(object):
deep = self._dynamic_config.myparams.get("deep", 0)
if depth is self._UNREACHABLE_DEPTH:
return True
- elif deep is True:
+ if deep is True:
return False
- else:
- # All non-integer cases are handled above,
- # so both values must be int type.
- return depth > deep
+ # All non-integer cases are handled above,
+ # so both values must be int type.
+ return depth > deep
def _depth_increment(self, depth, n=1):
"""
@@ -5941,7 +5931,7 @@ class depgraph(object):
return build_time == inst_pkg.build_time
- class _AutounmaskLevel(object):
+ class _AutounmaskLevel:
__slots__ = ("allow_use_changes", "allow_unstable_keywords", "allow_license_changes", \
"allow_missing_keywords", "allow_unmasks")
@@ -6169,8 +6159,7 @@ class depgraph(object):
if target_use is None:
if needed_use_config_change is None:
return pkg.use.enabled
- else:
- return needed_use_config_change[0]
+ return needed_use_config_change[0]
if needed_use_config_change is not None:
old_use = needed_use_config_change[0]
@@ -7484,7 +7473,7 @@ class depgraph(object):
mygraph.order.sort(key=cmp_sort_key(cmp_merge_preference))
- def altlist(self, reversed=DeprecationWarning):
+ def altlist(self, reversed=DeprecationWarning): # pylint: disable=redefined-builtin
if reversed is not DeprecationWarning:
warnings.warn("The reversed parameter of "
@@ -9263,7 +9252,7 @@ class depgraph(object):
filename = "world"
writemsg_stdout(
">>> Recording %s in \"%s\" favorites file...\n" %
- (colorize("INFORM", _unicode(a)), filename), noiselevel=-1)
+ (colorize("INFORM", str(a)), filename), noiselevel=-1)
world_set.update(all_added)
if world_locked:
@@ -9458,7 +9447,7 @@ class depgraph(object):
depgraph_sets = self._dynamic_config.sets[root_config.root]
args = []
for x in favorites:
- if not isinstance(x, basestring):
+ if not isinstance(x, str):
continue
if x in ("system", "world"):
x = SETPREFIX + x
@@ -9755,7 +9744,7 @@ class _dep_check_composite_db(dbapi):
if not avoid_update:
if not use_ebuild_visibility and usepkgonly:
return False
- elif not self._depgraph._equiv_ebuild_visible(pkg):
+ if not self._depgraph._equiv_ebuild_visible(pkg):
return False
if pkg.cp.startswith("virtual/"):
diff --git a/lib/_emerge/emergelog.py b/lib/_emerge/emergelog.py
index cb7bf77b3..3562f8eb3 100644
--- a/lib/_emerge/emergelog.py
+++ b/lib/_emerge/emergelog.py
@@ -1,10 +1,7 @@
# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import io
-import sys
import time
import portage
from portage import os
diff --git a/lib/_emerge/help.py b/lib/_emerge/help.py
index 2ccd323aa..de3d7b593 100644
--- a/lib/_emerge/help.py
+++ b/lib/_emerge/help.py
@@ -5,7 +5,7 @@ from __future__ import print_function
from portage.output import bold, turquoise, green
-def help():
+def emerge_help():
print(bold("emerge:")+" command-line interface to the Portage system")
print(bold("Usage:"))
print(" "+turquoise("emerge")+" [ "+green("options")+" ] [ "+green("action")+" ] [ "+turquoise("ebuild")+" | "+turquoise("tbz2")+" | "+turquoise("file")+" | "+turquoise("@set")+" | "+turquoise("atom")+" ] [ ... ]")
diff --git a/lib/_emerge/main.py b/lib/_emerge/main.py
index 95855ef2d..12323b17e 100644
--- a/lib/_emerge/main.py
+++ b/lib/_emerge/main.py
@@ -1,4 +1,4 @@
-# Copyright 1999-2019 Gentoo Authors
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
from __future__ import print_function
@@ -16,14 +16,12 @@ portage.proxy.lazyimport.lazyimport(globals(),
'textwrap',
'_emerge.actions:load_emerge_config,run_action,' + \
'validate_ebuild_environment',
- '_emerge.help:help@emerge_help',
+ '_emerge.help:emerge_help',
'_emerge.is_valid_package_atom:insert_category_into_atom'
)
from portage import os
from portage.sync import _SUBMODULE_PATH_MAP
-if sys.hexversion >= 0x3000000:
- long = int
options=[
"--alphabetical",
@@ -101,7 +99,7 @@ def insert_optional_args(args):
this feature natively.
"""
- class valid_integers(object):
+ class valid_integers:
def __contains__(self, s):
try:
return int(s) >= 0
@@ -110,7 +108,7 @@ def insert_optional_args(args):
valid_integers = valid_integers()
- class valid_floats(object):
+ class valid_floats:
def __contains__(self, s):
try:
return float(s) >= 0
@@ -1241,10 +1239,10 @@ def emerge_main(args=None):
if myaction == "help":
emerge_help()
return os.EX_OK
- elif myaction == "moo":
+ if myaction == "moo":
print(COWSAY_MOO % platform.system())
return os.EX_OK
- elif myaction == "sync":
+ if myaction == "sync":
# need to set this to True now in order for the repository config
# loading to allow new repos with non-existent directories
portage._sync_mode = True
diff --git a/lib/_emerge/resolver/DbapiProvidesIndex.py b/lib/_emerge/resolver/DbapiProvidesIndex.py
index 1650edd4e..8c7c05f06 100644
--- a/lib/_emerge/resolver/DbapiProvidesIndex.py
+++ b/lib/_emerge/resolver/DbapiProvidesIndex.py
@@ -1,11 +1,10 @@
-# Copyright 2015 Gentoo Foundation
+# Copyright 2015-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import bisect
import collections
-import sys
-class DbapiProvidesIndex(object):
+class DbapiProvidesIndex:
"""
The DbapiProvidesIndex class is used to wrap existing dbapi
interfaces, index packages by the sonames that they provide, and
@@ -73,9 +72,6 @@ class PackageDbapiProvidesIndex(DbapiProvidesIndex):
def __bool__(self):
return bool(self._db)
- if sys.hexversion < 0x3000000:
- __nonzero__ = __bool__
-
def __iter__(self):
return iter(self._db)
diff --git a/lib/_emerge/resolver/backtracking.py b/lib/_emerge/resolver/backtracking.py
index 430c81186..bc3fb3206 100644
--- a/lib/_emerge/resolver/backtracking.py
+++ b/lib/_emerge/resolver/backtracking.py
@@ -3,7 +3,7 @@
import copy
-class BacktrackParameter(object):
+class BacktrackParameter:
__slots__ = (
"circular_dependency",
@@ -65,7 +65,7 @@ class BacktrackParameter(object):
self.prune_rebuilds == other.prune_rebuilds
-class _BacktrackNode(object):
+class _BacktrackNode:
__slots__ = (
"parameter", "depth", "mask_steps", "terminal",
@@ -81,7 +81,7 @@ class _BacktrackNode(object):
return self.parameter == other.parameter
-class Backtracker(object):
+class Backtracker:
__slots__ = (
"_max_depth", "_unexplored_nodes", "_current_node", "_nodes", "_root",
@@ -119,8 +119,7 @@ class Backtracker(object):
node = self._unexplored_nodes.pop()
self._current_node = node
return copy.deepcopy(node.parameter)
- else:
- return None
+ return None
def __len__(self):
diff --git a/lib/_emerge/resolver/circular_dependency.py b/lib/_emerge/resolver/circular_dependency.py
index 5c119567b..d0c026dad 100644
--- a/lib/_emerge/resolver/circular_dependency.py
+++ b/lib/_emerge/resolver/circular_dependency.py
@@ -1,7 +1,7 @@
# Copyright 2010-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
from itertools import chain, product
import logging
@@ -13,7 +13,7 @@ from portage.util import writemsg_level
from _emerge.DepPrioritySatisfiedRange import DepPrioritySatisfiedRange
from _emerge.Package import Package
-class circular_dependency_handler(object):
+class circular_dependency_handler:
MAX_AFFECTING_USE = 10
diff --git a/lib/_emerge/resolver/output.py b/lib/_emerge/resolver/output.py
index ed88cc51f..9483898de 100644
--- a/lib/_emerge/resolver/output.py
+++ b/lib/_emerge/resolver/output.py
@@ -1,16 +1,13 @@
-# Copyright 2010-2019 Gentoo Authors
+# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
"""Resolver output display operation.
"""
-from __future__ import unicode_literals
-
__all__ = (
"Display", "format_unmatched_atom",
)
-import sys
import portage
from portage import os
@@ -34,13 +31,7 @@ from _emerge.resolver.output_helpers import ( _DisplayConfig, _tree_display,
_PackageCounters, _create_use_string, _calc_changelog, PkgInfo)
from _emerge.show_invalid_depstring_notice import show_invalid_depstring_notice
-if sys.hexversion >= 0x3000000:
- basestring = str
- _unicode = str
-else:
- _unicode = unicode
-
-class Display(object):
+class Display:
"""Formats and outputs the depgrah supplied it for merge/re-merge, etc.
__call__()
@@ -88,19 +79,19 @@ class Display(object):
addl = "%s " % (colorize(self.blocker_style, "B"),)
addl += self.empty_space_in_brackets()
self.resolved = dep_expand(
- _unicode(blocker.atom).lstrip("!"), mydb=self.vardb,
+ str(blocker.atom).lstrip("!"), mydb=self.vardb,
settings=self.pkgsettings
)
if self.conf.columns and self.conf.quiet:
- addl += " " + colorize(self.blocker_style, _unicode(self.resolved))
+ addl += " " + colorize(self.blocker_style, str(self.resolved))
else:
addl = "[%s %s] %s%s" % \
(colorize(self.blocker_style, "blocks"),
addl, self.indent,
- colorize(self.blocker_style, _unicode(self.resolved))
+ colorize(self.blocker_style, str(self.resolved))
)
block_parents = self.conf.blocker_parents.parent_nodes(blocker)
- block_parents = set(_unicode(pnode.cpv) for pnode in block_parents)
+ block_parents = set(str(pnode.cpv) for pnode in block_parents)
block_parents = ", ".join(block_parents)
if blocker.atom.blocker.overlap.forbid:
blocking_desc = "hard blocking"
@@ -109,7 +100,7 @@ class Display(object):
if self.resolved != blocker.atom:
addl += colorize(self.blocker_style,
" (\"%s\" is %s %s)" %
- (_unicode(blocker.atom).lstrip("!"),
+ (str(blocker.atom).lstrip("!"),
blocking_desc, block_parents))
else:
addl += colorize(self.blocker_style,
@@ -269,26 +260,24 @@ class Display(object):
if pkg_info.built:
if pkg_info.system:
return colorize("PKG_BINARY_MERGE_SYSTEM", pkg_str)
- elif pkg_info.world:
+ if pkg_info.world:
return colorize("PKG_BINARY_MERGE_WORLD", pkg_str)
- else:
- return colorize("PKG_BINARY_MERGE", pkg_str)
- else:
- if pkg_info.system:
- return colorize("PKG_MERGE_SYSTEM", pkg_str)
- elif pkg_info.world:
- return colorize("PKG_MERGE_WORLD", pkg_str)
- else:
- return colorize("PKG_MERGE", pkg_str)
- elif pkg_info.operation == "uninstall":
- return colorize("PKG_UNINSTALL", pkg_str)
- else:
+ return colorize("PKG_BINARY_MERGE", pkg_str)
+
if pkg_info.system:
- return colorize("PKG_NOMERGE_SYSTEM", pkg_str)
- elif pkg_info.world:
- return colorize("PKG_NOMERGE_WORLD", pkg_str)
- else:
- return colorize("PKG_NOMERGE", pkg_str)
+ return colorize("PKG_MERGE_SYSTEM", pkg_str)
+ if pkg_info.world:
+ return colorize("PKG_MERGE_WORLD", pkg_str)
+ return colorize("PKG_MERGE", pkg_str)
+
+ if pkg_info.operation == "uninstall":
+ return colorize("PKG_UNINSTALL", pkg_str)
+
+ if pkg_info.system:
+ return colorize("PKG_NOMERGE_SYSTEM", pkg_str)
+ if pkg_info.world:
+ return colorize("PKG_NOMERGE_WORLD", pkg_str)
+ return colorize("PKG_NOMERGE", pkg_str)
def verbose_size(self, pkg, repoadd_set, pkg_info):
@@ -316,7 +305,7 @@ class Display(object):
depstr, = db.aux_get(pkg.cpv,
["SRC_URI"], myrepo=pkg.repo)
show_invalid_depstring_notice(
- pkg, _unicode(e))
+ pkg, str(e))
raise
except SignatureException:
# missing/invalid binary package SIZE signature
@@ -447,7 +436,7 @@ class Display(object):
ver_str = self._append_slot(ver_str, pkg, pkg_info)
ver_str = self._append_repository(ver_str, pkg, pkg_info)
if self.conf.quiet:
- myprint = _unicode(pkg_info.attr_display) + " " + self.indent + \
+ myprint = str(pkg_info.attr_display) + " " + self.indent + \
self.pkgprint(pkg_info.cp, pkg_info)
myprint = myprint+darkblue(" "+ver_str)+" "
myprint = myprint+pkg_info.oldbest
@@ -486,7 +475,7 @@ class Display(object):
ver_str = self._append_slot(ver_str, pkg, pkg_info)
ver_str = self._append_repository(ver_str, pkg, pkg_info)
if self.conf.quiet:
- myprint = _unicode(pkg_info.attr_display) + " " + self.indent + \
+ myprint = str(pkg_info.attr_display) + " " + self.indent + \
self.pkgprint(pkg_info.cp, pkg_info)
myprint = myprint+" "+green(ver_str)+" "
myprint = myprint+pkg_info.oldbest
@@ -543,7 +532,7 @@ class Display(object):
@param show_repos: bool.
"""
for msg in self.print_msg:
- if isinstance(msg, basestring):
+ if isinstance(msg, str):
writemsg_stdout("%s\n" % (msg,), noiselevel=-1)
continue
myprint, self.verboseadd, repoadd = msg
diff --git a/lib/_emerge/resolver/output_helpers.py b/lib/_emerge/resolver/output_helpers.py
index b83717e93..25aa925b4 100644
--- a/lib/_emerge/resolver/output_helpers.py
+++ b/lib/_emerge/resolver/output_helpers.py
@@ -1,18 +1,15 @@
-# Copyright 2010-2014 Gentoo Foundation
+# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
"""Contains private support functions for the Display class
in output.py
"""
-from __future__ import unicode_literals
-
__all__ = (
)
import io
import re
-import sys
from portage import os
from portage import _encodings, _unicode_encode
@@ -30,11 +27,7 @@ from _emerge.Blocker import Blocker
from _emerge.Package import Package
-if sys.hexversion >= 0x3000000:
- basestring = str
-
-
-class _RepoDisplay(object):
+class _RepoDisplay:
def __init__(self, roots):
self._shown_repos = {}
self._unknown_repo = False
@@ -82,16 +75,8 @@ class _RepoDisplay(object):
" indicates that the source repository could not be determined\n")
return "".join(output)
- if sys.hexversion < 0x3000000:
-
- __unicode__ = __str__
-
- def __str__(self):
- return _unicode_encode(self.__unicode__(),
- encoding=_encodings['content'])
-
-class _PackageCounters(object):
+class _PackageCounters:
def __init__(self):
self.upgrades = 0
@@ -169,7 +154,7 @@ class _PackageCounters(object):
return "".join(myoutput)
-class _DisplayConfig(object):
+class _DisplayConfig:
def __init__(self, depgraph, mylist, favorites, verbosity):
frozen_config = depgraph._frozen_config
@@ -484,7 +469,7 @@ def _prune_tree_display(display_list):
del display_list[i]
-def _calc_changelog(ebuildpath,current,next):
+def _calc_changelog(ebuildpath,current,next): # pylint: disable=redefined-builtin
if ebuildpath == None or not os.path.exists(ebuildpath):
return []
current = '-'.join(catpkgsplit(current)[1:])
@@ -599,7 +584,7 @@ def _find_changelog_tags(changelog):
_strip_header_comments(changelog[release_end:].splitlines())))
return divs
-class PkgInfo(object):
+class PkgInfo:
"""Simple class to hold instance attributes for current
information about the pkg being printed.
"""
@@ -683,11 +668,3 @@ class PkgAttrDisplay(SlotObject):
output.append(self.mask)
return "".join(output)
-
- if sys.hexversion < 0x3000000:
-
- __unicode__ = __str__
-
- def __str__(self):
- return _unicode_encode(self.__unicode__(),
- encoding=_encodings['content'])
diff --git a/lib/_emerge/resolver/package_tracker.py b/lib/_emerge/resolver/package_tracker.py
index ccb0b11cf..2afa7923b 100644
--- a/lib/_emerge/resolver/package_tracker.py
+++ b/lib/_emerge/resolver/package_tracker.py
@@ -29,7 +29,7 @@ class PackageConflict(_PackageConflict):
return len(self.pkgs)
-class PackageTracker(object):
+class PackageTracker:
"""
**Behavior**
@@ -358,7 +358,7 @@ class PackageTracker(object):
return self.contains(pkg, installed=True)
-class PackageTrackerDbapiWrapper(object):
+class PackageTrackerDbapiWrapper:
"""
A wrpper class that provides parts of the legacy
dbapi interface. Remove it once all consumers have
diff --git a/lib/_emerge/resolver/slot_collision.py b/lib/_emerge/resolver/slot_collision.py
index 682a3a0a5..cc16287de 100644
--- a/lib/_emerge/resolver/slot_collision.py
+++ b/lib/_emerge/resolver/slot_collision.py
@@ -1,9 +1,8 @@
-# Copyright 2010-2014 Gentoo Foundation
+# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
-import sys
from portage import _encodings, _unicode_encode
from _emerge.AtomArg import AtomArg
@@ -16,10 +15,8 @@ from portage._sets.base import InternalPackageSet
from portage.util import writemsg
from portage.versions import cpv_getversion, vercmp
-if sys.hexversion >= 0x3000000:
- basestring = str
-class slot_conflict_handler(object):
+class slot_conflict_handler:
"""This class keeps track of all slot conflicts and provides
an interface to get possible solutions.
@@ -374,11 +371,11 @@ class slot_conflict_handler(object):
selected_for_display = set()
unconditional_use_deps = set()
- for (type, sub_type), parents in collision_reasons.items():
- #From each (type, sub_type) pair select at least one atom.
+ for (ctype, sub_type), parents in collision_reasons.items():
+ #From each (ctype, sub_type) pair select at least one atom.
#Try to select as few atoms as possible
- if type == "version":
+ if ctype == "version":
#Find the atom with version that is as far away as possible.
best_matches = {}
for ppkg, atom, other_pkg in parents:
@@ -398,7 +395,7 @@ class slot_conflict_handler(object):
if not verboseconflicts:
selected_for_display.update(
best_matches.values())
- elif type in ("soname", "slot"):
+ elif ctype in ("soname", "slot"):
# Check for packages that might need to
# be rebuilt, but cannot be rebuilt for
# some reason.
@@ -426,7 +423,7 @@ class slot_conflict_handler(object):
selected_for_display.add((ppkg, atom))
if not verboseconflicts:
break
- elif type == "use":
+ elif ctype == "use":
#Prefer atoms with unconditional use deps over, because it's
#not possible to change them on the parent, which means there
#are fewer possible solutions.
@@ -467,7 +464,7 @@ class slot_conflict_handler(object):
# If the list is long, people can simply
# use a pager.
selected_for_display.add((ppkg, atom))
- elif type == "AtomArg":
+ elif ctype == "AtomArg":
for ppkg, atom in parents:
selected_for_display.add((ppkg, atom))
@@ -739,9 +736,9 @@ class slot_conflict_handler(object):
all_involved_flags = []
#Go through all slot conflicts
- for id, pkg in enumerate(config):
+ for idx, pkg in enumerate(config):
involved_flags = {}
- for ppkg, atom in all_conflict_atoms_by_slotatom[id]:
+ for ppkg, atom in all_conflict_atoms_by_slotatom[idx]:
if not atom.package:
continue
@@ -849,8 +846,8 @@ class slot_conflict_handler(object):
if self.debug:
writemsg("All involved flags:\n", noiselevel=-1)
- for id, involved_flags in enumerate(all_involved_flags):
- writemsg(" %s\n" % (config[id],), noiselevel=-1)
+ for idx, involved_flags in enumerate(all_involved_flags):
+ writemsg(" %s\n" % (config[idx],), noiselevel=-1)
for flag, state in involved_flags.items():
writemsg(" " + flag + ": " + state + "\n", noiselevel=-1)
@@ -1068,10 +1065,9 @@ class slot_conflict_handler(object):
if is_valid_solution and required_changes:
return required_changes
- else:
- return None
+ return None
-class _configuration_generator(object):
+class _configuration_generator:
def __init__(self, conflict_pkgs):
#reorder packages such that installed packages come last
self.conflict_pkgs = []
@@ -1098,11 +1094,11 @@ class _configuration_generator(object):
return None
solution = []
- for id, pkgs in enumerate(self.conflict_pkgs):
- solution.append(pkgs[self.solution_ids[id]])
+ for idx, pkgs in enumerate(self.conflict_pkgs):
+ solution.append(pkgs[self.solution_ids[idx]])
return solution
- def _next(self, id=None):
+ def _next(self, id=None): # pylint: disable=redefined-builtin
solution_ids = self.solution_ids
conflict_pkgs = self.conflict_pkgs
@@ -1112,34 +1108,24 @@ class _configuration_generator(object):
if solution_ids[id] == len(conflict_pkgs[id])-1:
if id > 0:
return self._next(id=id-1)
- else:
- return False
- else:
- solution_ids[id] += 1
- for other_id in range(id+1, len(solution_ids)):
- solution_ids[other_id] = 0
- return True
+ return False
+
+ solution_ids[id] += 1
+ for other_id in range(id+1, len(solution_ids)):
+ solution_ids[other_id] = 0
+ return True
-class _solution_candidate_generator(object):
- class _value_helper(object):
+class _solution_candidate_generator:
+ class _value_helper:
def __init__(self, value=None):
self.value = value
def __eq__(self, other):
- if isinstance(other, basestring):
+ if isinstance(other, str):
return self.value == other
- else:
- return self.value == other.value
+ return self.value == other.value
def __str__(self):
return "%s" % (self.value,)
- if sys.hexversion < 0x3000000:
-
- __unicode__ = __str__
-
- def __str__(self):
- return _unicode_encode(self.__unicode__(),
- encoding=_encodings['content'], errors='backslashreplace')
-
def __init__(self, all_involved_flags):
#A copy of all_involved_flags with all "cond" values
#replaced by a _value_helper object.
@@ -1171,7 +1157,7 @@ class _solution_candidate_generator(object):
return self.all_involved_flags
- def _next(self, id=None):
+ def _next(self, id=None): # pylint: disable=redefined-builtin
values = self.conditional_values
if not values:
@@ -1183,12 +1169,11 @@ class _solution_candidate_generator(object):
if values[id].value == "enabled":
if id > 0:
return self._next(id=id-1)
- else:
- return False
- else:
- values[id].value = "enabled"
- for other_id in range(id+1, len(values)):
- values[other_id].value = "disabled"
- return True
+ return False
+
+ values[id].value = "enabled"
+ for other_id in range(id+1, len(values)):
+ values[other_id].value = "disabled"
+ return True
diff --git a/lib/_emerge/search.py b/lib/_emerge/search.py
index be639dfa3..000c427e0 100644
--- a/lib/_emerge/search.py
+++ b/lib/_emerge/search.py
@@ -1,8 +1,6 @@
# Copyright 1999-2016 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import difflib
import re
import portage
@@ -17,7 +15,7 @@ from portage.util.iterators.MultiIterGroupBy import MultiIterGroupBy
from _emerge.Package import Package
-class search(object):
+class search:
#
# class constants
@@ -358,7 +356,7 @@ class search(object):
def output(self):
"""Outputs the results of the search."""
- class msg(object):
+ class msg:
@staticmethod
def append(msg):
writemsg_stdout(msg, noiselevel=-1)
@@ -411,7 +409,7 @@ class search(object):
desc = metadata["DESCRIPTION"]
homepage = metadata["HOMEPAGE"]
- license = metadata["LICENSE"]
+ license = metadata["LICENSE"] # pylint: disable=redefined-builtin
if masked:
msg.append(green("*") + " " + \
@@ -528,4 +526,3 @@ class search(object):
else:
result = ""
return result
-
diff --git a/lib/_emerge/show_invalid_depstring_notice.py b/lib/_emerge/show_invalid_depstring_notice.py
index e11ea65ed..a2f29eae6 100644
--- a/lib/_emerge/show_invalid_depstring_notice.py
+++ b/lib/_emerge/show_invalid_depstring_notice.py
@@ -32,4 +32,3 @@ def show_invalid_depstring_notice(parent_node, error_msg):
msg2 = "".join("%s\n" % line for line in textwrap.wrap("".join(msg), 72))
writemsg_level(msg1 + msg2, level=logging.ERROR, noiselevel=-1)
-
diff --git a/lib/_emerge/stdout_spinner.py b/lib/_emerge/stdout_spinner.py
index 670686adf..26592b7b0 100644
--- a/lib/_emerge/stdout_spinner.py
+++ b/lib/_emerge/stdout_spinner.py
@@ -7,7 +7,7 @@ import time
from portage.output import darkgreen, green
-class stdout_spinner(object):
+class stdout_spinner:
scroll_msgs = [
"Gentoo Rocks ("+platform.system()+")",
"Thank you for using Gentoo. :)",
diff --git a/lib/_emerge/unmerge.py b/lib/_emerge/unmerge.py
index 8923e20ea..8de35a6ef 100644
--- a/lib/_emerge/unmerge.py
+++ b/lib/_emerge/unmerge.py
@@ -98,8 +98,8 @@ def _unmerge_display(root_config, myopts, unmerge_action,
" can only be used with specific package names")
print()
return 1, {}
- else:
- global_unmerge = 1
+
+ global_unmerge = 1
localtree = vartree
# process all arguments and add all
@@ -605,4 +605,3 @@ def unmerge(root_config, myopts, unmerge_action,
sets["selected"].unlock()
return os.EX_OK
-
diff --git a/lib/portage/__init__.py b/lib/portage/__init__.py
index ec667e478..2d8e4e8e4 100644
--- a/lib/portage/__init__.py
+++ b/lib/portage/__init__.py
@@ -1,8 +1,6 @@
-# Copyright 1998-2019 Gentoo Authors
+# Copyright 1998-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
VERSION = "HEAD"
# ===========================================================================
@@ -136,10 +134,6 @@ except ImportError as e:
sys.stderr.write(" "+str(e)+"\n\n")
raise
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
- long = int
# We use utf_8 encoding everywhere. Previously, we used
# sys.getfilesystemencoding() for the 'merge' encoding, but that had
@@ -170,45 +164,32 @@ _encodings = {
'stdio' : 'utf_8',
}
-if sys.hexversion >= 0x3000000:
- def _decode_argv(argv):
- # With Python 3, the surrogateescape encoding error handler makes it
- # possible to access the original argv bytes, which can be useful
- # if their actual encoding does no match the filesystem encoding.
- fs_encoding = sys.getfilesystemencoding()
- return [_unicode_decode(x.encode(fs_encoding, 'surrogateescape'))
- for x in argv]
+def _decode_argv(argv):
+ # With Python 3, the surrogateescape encoding error handler makes it
+ # possible to access the original argv bytes, which can be useful
+ # if their actual encoding does no match the filesystem encoding.
+ fs_encoding = sys.getfilesystemencoding()
+ return [_unicode_decode(x.encode(fs_encoding, 'surrogateescape'))
+ for x in argv]
- def _unicode_encode(s, encoding=_encodings['content'], errors='backslashreplace'):
- if isinstance(s, str):
- s = s.encode(encoding, errors)
- return s
- def _unicode_decode(s, encoding=_encodings['content'], errors='replace'):
- if isinstance(s, bytes):
- s = str(s, encoding=encoding, errors=errors)
- return s
+def _unicode_encode(s, encoding=_encodings['content'], errors='backslashreplace'):
+ if isinstance(s, str):
+ s = s.encode(encoding, errors)
+ return s
- _native_string = _unicode_decode
-else:
- def _decode_argv(argv):
- return [_unicode_decode(x) for x in argv]
+def _unicode_decode(s, encoding=_encodings['content'], errors='replace'):
+ if isinstance(s, bytes):
+ s = str(s, encoding=encoding, errors=errors)
+ return s
- def _unicode_encode(s, encoding=_encodings['content'], errors='backslashreplace'):
- if isinstance(s, unicode):
- s = s.encode(encoding, errors)
- return s
- def _unicode_decode(s, encoding=_encodings['content'], errors='replace'):
- if isinstance(s, bytes):
- s = unicode(s, encoding=encoding, errors=errors)
- return s
+_native_string = _unicode_decode
- _native_string = _unicode_encode
-class _unicode_func_wrapper(object):
+class _unicode_func_wrapper:
"""
Wraps a function, converts arguments from unicode to bytes,
and return values to unicode from bytes. Function calls
@@ -267,7 +248,7 @@ class _unicode_func_wrapper(object):
return rval
-class _unicode_module_wrapper(object):
+class _unicode_module_wrapper:
"""
Wraps a module and wraps all functions with _unicode_func_wrapper.
"""
@@ -308,7 +289,7 @@ class _unicode_module_wrapper(object):
cache[attr] = result
return result
-class _eintr_func_wrapper(object):
+class _eintr_func_wrapper:
"""
Wraps a function and handles EINTR by calling the function as
many times as necessary (until it returns without raising EINTR).
@@ -417,7 +398,7 @@ bsd_chflags = None
if platform.system() in ('FreeBSD',):
# TODO: remove this class?
- class bsd_chflags(object):
+ class bsd_chflags:
chflags = os.chflags
lchflags = os.lchflags
@@ -479,7 +460,7 @@ def _eapi_is_deprecated(eapi):
return eapi in _deprecated_eapis
def eapi_is_supported(eapi):
- if not isinstance(eapi, basestring):
+ if not isinstance(eapi, str):
# Only call str() when necessary since with python2 it
# can trigger UnicodeEncodeError if EAPI is corrupt.
eapi = str(eapi)
@@ -620,10 +601,10 @@ if VERSION == 'HEAD':
head_timestamp = None
if len(output_lines) > 3:
try:
- head_timestamp = long(output_lines[3])
+ head_timestamp = int(output_lines[3])
except ValueError:
pass
- timestamp = long(time.time())
+ timestamp = int(time.time())
if head_timestamp is not None and timestamp > head_timestamp:
timestamp = timestamp - head_timestamp
if not patchlevel:
diff --git a/lib/portage/_emirrordist/Config.py b/lib/portage/_emirrordist/Config.py
index c1f59f725..56732089e 100644
--- a/lib/portage/_emirrordist/Config.py
+++ b/lib/portage/_emirrordist/Config.py
@@ -1,20 +1,18 @@
-# Copyright 2013-2019 Gentoo Authors
+# Copyright 2013-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import copy
import io
import logging
import shelve
-import sys
import time
import portage
from portage import os
from portage.package.ebuild.fetch import MirrorLayoutConfig
from portage.util import grabdict, grablines
-from portage.util._ShelveUnicodeWrapper import ShelveUnicodeWrapper
-class Config(object):
+class Config:
def __init__(self, options, portdb, event_loop):
self.options = options
self.portdb = portdb
@@ -97,7 +95,7 @@ class Config(object):
return self._LogFormatter(line_format, log_func)
- class _LogFormatter(object):
+ class _LogFormatter:
__slots__ = ('_line_format', '_log_func')
@@ -126,9 +124,6 @@ class Config(object):
from bsddb3 import dbshelve
db = dbshelve.open(db_file, flags=open_flag)
- if sys.hexversion < 0x3000000:
- db = ShelveUnicodeWrapper(db)
-
if self.options.dry_run:
logging.warning("dry-run: %s db opened in readonly mode" % db_desc)
if not isinstance(db, dict):
diff --git a/lib/portage/_emirrordist/DeletionIterator.py b/lib/portage/_emirrordist/DeletionIterator.py
index 3cbff2c3a..08985ed6c 100644
--- a/lib/portage/_emirrordist/DeletionIterator.py
+++ b/lib/portage/_emirrordist/DeletionIterator.py
@@ -7,7 +7,7 @@ import stat
from portage import os
from .DeletionTask import DeletionTask
-class DeletionIterator(object):
+class DeletionIterator:
def __init__(self, config):
self._config = config
diff --git a/lib/portage/_emirrordist/FetchIterator.py b/lib/portage/_emirrordist/FetchIterator.py
index 4ad797502..fe521c346 100644
--- a/lib/portage/_emirrordist/FetchIterator.py
+++ b/lib/portage/_emirrordist/FetchIterator.py
@@ -15,7 +15,7 @@ from .FetchTask import FetchTask
from _emerge.CompositeTask import CompositeTask
-class FetchIterator(object):
+class FetchIterator:
def __init__(self, config):
self._config = config
diff --git a/lib/portage/_emirrordist/FetchTask.py b/lib/portage/_emirrordist/FetchTask.py
index 322de79ba..f2342362d 100644
--- a/lib/portage/_emirrordist/FetchTask.py
+++ b/lib/portage/_emirrordist/FetchTask.py
@@ -1,4 +1,4 @@
-# Copyright 2013-2019 Gentoo Authors
+# Copyright 2013-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
from __future__ import division
@@ -7,9 +7,7 @@ import collections
import errno
import logging
import random
-import stat
import subprocess
-import sys
import portage
from portage import _encodings, _unicode_encode
@@ -232,12 +230,11 @@ class FetchTask(CompositeTask):
if self._fs_mirror_stack:
self._fetch_fs(self._fs_mirror_stack.pop())
return
- else:
- uri = self._next_uri()
- if uri is not None:
- self._tried_uris.add(uri)
- self._fetch_uri(uri)
- return
+ uri = self._next_uri()
+ if uri is not None:
+ self._tried_uris.add(uri)
+ self._fetch_uri(uri)
+ return
if self._tried_uris:
msg = "all uris failed"
@@ -352,14 +349,14 @@ class FetchTask(CompositeTask):
self.returncode = os.EX_OK
self.wait()
return
- else:
- self._start_task(
- FileCopier(src_path=src, dest_path=dest,
- background=(self.background and
- self._log_path is not None),
- logfile=self._log_path),
- self._fs_mirror_copier_exit)
- return
+
+ self._start_task(
+ FileCopier(src_path=src, dest_path=dest,
+ background=(self.background and
+ self._log_path is not None),
+ logfile=self._log_path),
+ self._fs_mirror_copier_exit)
+ return
self._try_next_mirror()
@@ -385,14 +382,9 @@ class FetchTask(CompositeTask):
# Apply the timestamp from the source file, but
# just rely on umask for permissions.
try:
- if sys.hexversion >= 0x3030000:
- os.utime(copier.dest_path,
- ns=(self._current_stat.st_mtime_ns,
- self._current_stat.st_mtime_ns))
- else:
- os.utime(copier.dest_path,
- (self._current_stat[stat.ST_MTIME],
- self._current_stat[stat.ST_MTIME]))
+ os.utime(copier.dest_path,
+ ns=(self._current_stat.st_mtime_ns,
+ self._current_stat.st_mtime_ns))
except OSError as e:
msg = "%s %s utime failed unexpectedly: %s" % \
(self.distfile, current_mirror.name, e)
@@ -605,11 +597,10 @@ class FetchTask(CompositeTask):
def _select_hash(self):
if default_hash_name in self.digests:
return default_hash_name
- else:
- for hash_name in self.digests:
- if hash_name != "size" and \
- hash_name in portage.checksum.get_valid_checksum_keys():
- return hash_name
+ for hash_name in self.digests:
+ if hash_name != "size" and \
+ hash_name in portage.checksum.get_valid_checksum_keys():
+ return hash_name
return None
diff --git a/lib/portage/_emirrordist/MirrorDistTask.py b/lib/portage/_emirrordist/MirrorDistTask.py
index 8eb3081c6..e495ab9bf 100644
--- a/lib/portage/_emirrordist/MirrorDistTask.py
+++ b/lib/portage/_emirrordist/MirrorDistTask.py
@@ -1,9 +1,8 @@
-# Copyright 2013-2018 Gentoo Foundation
+# Copyright 2013-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import errno
import logging
-import sys
import time
try:
@@ -18,9 +17,6 @@ from _emerge.CompositeTask import CompositeTask
from .FetchIterator import FetchIterator
from .DeletionIterator import DeletionIterator
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- long = int
class MirrorDistTask(CompositeTask):
@@ -111,7 +107,7 @@ class MirrorDistTask(CompositeTask):
recycle_db[filename] = (st.st_size, start_time)
else:
r_size, r_time = value
- if long(r_size) != st.st_size:
+ if int(r_size) != st.st_size:
recycle_db[filename] = (st.st_size, start_time)
elif r_time + r_deletion_delay < start_time:
if self._config.options.dry_run:
diff --git a/lib/portage/_emirrordist/main.py b/lib/portage/_emirrordist/main.py
index ce0c2929f..23f6468c5 100644
--- a/lib/portage/_emirrordist/main.py
+++ b/lib/portage/_emirrordist/main.py
@@ -1,4 +1,4 @@
-# Copyright 2013-2015 Gentoo Foundation
+# Copyright 2013-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import argparse
@@ -14,9 +14,6 @@ from portage.util._eventloop.global_event_loop import global_event_loop
from .Config import Config
from .MirrorDistTask import MirrorDistTask
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- long = int
seconds_per_day = 24 * 60 * 60
@@ -318,7 +315,7 @@ def emirrordist_main(args):
parser.error("--scheduled-deletion-log requires --deletion-db")
if options.deletion_delay is not None:
- options.deletion_delay = long(options.deletion_delay)
+ options.deletion_delay = int(options.deletion_delay)
if options.deletion_db is None:
parser.error("--deletion-delay requires --deletion-db")
@@ -391,7 +388,7 @@ def emirrordist_main(args):
if options.recycle_deletion_delay is not None:
options.recycle_deletion_delay = \
- long(options.recycle_deletion_delay)
+ int(options.recycle_deletion_delay)
if options.fetch_log_dir is not None:
options.fetch_log_dir = normalize_path(
diff --git a/lib/portage/_global_updates.py b/lib/portage/_global_updates.py
index 6a595da56..730ade592 100644
--- a/lib/portage/_global_updates.py
+++ b/lib/portage/_global_updates.py
@@ -149,8 +149,7 @@ def _do_global_updates(trees, prev_mtimes, quiet=False, if_mtime_changed=True):
if portdb.match(atoma):
world_warnings.add((atoma, atomb))
return True
- else:
- return False
+ return False
for update_cmd in myupd:
for pos, atom in enumerate(world_list):
diff --git a/lib/portage/_legacy_globals.py b/lib/portage/_legacy_globals.py
index 45113d150..a9f8aa62d 100644
--- a/lib/portage/_legacy_globals.py
+++ b/lib/portage/_legacy_globals.py
@@ -15,7 +15,7 @@ def _get_legacy_global(name):
constructed.add(name)
return getattr(portage, name)
- elif name in ('mtimedb', 'mtimedbfile'):
+ if name in ('mtimedb', 'mtimedbfile'):
portage.mtimedbfile = os.path.join(portage.settings['EROOT'],
CACHE_PATH, "mtimedb")
constructed.add('mtimedbfile')
diff --git a/lib/portage/_selinux.py b/lib/portage/_selinux.py
index 49e2e8e58..aba40c2dd 100644
--- a/lib/portage/_selinux.py
+++ b/lib/portage/_selinux.py
@@ -5,7 +5,6 @@
# the whole _selinux module itself will be wrapped.
import os
import shutil
-import sys
import warnings
try:
@@ -23,8 +22,6 @@ def copyfile(src, dest):
dest = _native_string(dest, encoding=_encodings['fs'], errors='strict')
(rc, ctx) = selinux.lgetfilecon(src)
if rc < 0:
- if sys.hexversion < 0x3000000:
- src = _unicode_decode(src, encoding=_encodings['fs'], errors='replace')
raise OSError(_("copyfile: Failed getting context of \"%s\".") % src)
setfscreate(ctx)
@@ -48,8 +45,6 @@ def mkdir(target, refdir):
refdir = _native_string(refdir, encoding=_encodings['fs'], errors='strict')
(rc, ctx) = selinux.getfilecon(refdir)
if rc < 0:
- if sys.hexversion < 0x3000000:
- refdir = _unicode_decode(refdir, encoding=_encodings['fs'], errors='replace')
raise OSError(
_("mkdir: Failed getting context of reference directory \"%s\".") \
% refdir)
@@ -65,8 +60,6 @@ def rename(src, dest):
dest = _native_string(dest, encoding=_encodings['fs'], errors='strict')
(rc, ctx) = selinux.lgetfilecon(src)
if rc < 0:
- if sys.hexversion < 0x3000000:
- src = _unicode_decode(src, encoding=_encodings['fs'], errors='replace')
raise OSError(_("rename: Failed getting context of \"%s\".") % src)
setfscreate(ctx)
@@ -98,8 +91,6 @@ def setexec(ctx="\n"):
portage.writemsg("!!! %s\n" % msg, noiselevel=-1)
if rc < 0:
- if sys.hexversion < 0x3000000:
- ctx = _unicode_decode(ctx, encoding=_encodings['content'], errors='replace')
if selinux.security_getenforce() == 1:
raise OSError(_("Failed setting exec() context \"%s\".") % ctx)
else:
@@ -110,12 +101,10 @@ def setexec(ctx="\n"):
def setfscreate(ctx="\n"):
ctx = _native_string(ctx, encoding=_encodings['content'], errors='strict')
if selinux.setfscreatecon(ctx) < 0:
- if sys.hexversion < 0x3000000:
- ctx = _unicode_decode(ctx, encoding=_encodings['content'], errors='replace')
raise OSError(
_("setfscreate: Failed setting fs create context \"%s\".") % ctx)
-class spawn_wrapper(object):
+class spawn_wrapper:
"""
Create a wrapper function for the given spawn function. When the wrapper
is called, it will adjust the arguments such that setexec() to be called
@@ -148,8 +137,6 @@ def symlink(target, link, reflnk):
reflnk = _native_string(reflnk, encoding=_encodings['fs'], errors='strict')
(rc, ctx) = selinux.lgetfilecon(reflnk)
if rc < 0:
- if sys.hexversion < 0x3000000:
- reflnk = _unicode_decode(reflnk, encoding=_encodings['fs'], errors='replace')
raise OSError(
_("symlink: Failed getting context of reference symlink \"%s\".") \
% reflnk)
diff --git a/lib/portage/_sets/__init__.py b/lib/portage/_sets/__init__.py
index a569b273b..6c6df4cca 100644
--- a/lib/portage/_sets/__init__.py
+++ b/lib/portage/_sets/__init__.py
@@ -29,17 +29,16 @@ SETPREFIX = "@"
def get_boolean(options, name, default):
if not name in options:
return default
- elif options[name].lower() in ("1", "yes", "on", "true"):
+ if options[name].lower() in ("1", "yes", "on", "true"):
return True
- elif options[name].lower() in ("0", "no", "off", "false"):
+ if options[name].lower() in ("0", "no", "off", "false"):
return False
- else:
- raise SetConfigError(_("invalid value '%(value)s' for option '%(option)s'") % {"value": options[name], "option": name})
+ raise SetConfigError(_("invalid value '%(value)s' for option '%(option)s'") % {"value": options[name], "option": name})
class SetConfigError(Exception):
pass
-class SetConfig(object):
+class SetConfig:
def __init__(self, paths, settings, trees):
self._parser = SafeConfigParser(
defaults={
diff --git a/lib/portage/_sets/base.py b/lib/portage/_sets/base.py
index aba295602..06e0a3cd4 100644
--- a/lib/portage/_sets/base.py
+++ b/lib/portage/_sets/base.py
@@ -1,18 +1,14 @@
-# Copyright 2007-2018 Gentoo Foundation
+# Copyright 2007-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-import sys
from portage.dep import Atom, ExtendedAtomDict, best_match_to_list, match_from_list
from portage.exception import InvalidAtom
from portage.versions import cpv_getkey
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
OPERATIONS = ["merge", "unmerge"]
-class PackageSet(object):
+class PackageSet:
# Set this to operations that are supported by your subclass. While
# technically there is no difference between "merge" and "unmerge" regarding
# package sets, the latter doesn't make sense for some sets like "system"
@@ -46,9 +42,6 @@ class PackageSet(object):
self._load()
return bool(self._atoms or self._nonatoms)
- if sys.hexversion < 0x3000000:
- __nonzero__ = __bool__
-
def supportsOperation(self, op):
if not op in OPERATIONS:
raise ValueError(op)
@@ -74,7 +67,7 @@ class PackageSet(object):
self._nonatoms.clear()
for a in atoms:
if not isinstance(a, Atom):
- if isinstance(a, basestring):
+ if isinstance(a, str):
a = a.strip()
if not a:
continue
@@ -107,8 +100,7 @@ class PackageSet(object):
def getMetadata(self, key):
if hasattr(self, key.lower()):
return getattr(self, key.lower())
- else:
- return ""
+ return ""
def _updateAtomMap(self, atoms=None):
"""Update self._atommap for specific atoms or all atoms."""
diff --git a/lib/portage/_sets/dbapi.py b/lib/portage/_sets/dbapi.py
index 5c600ec9e..a9e1b6880 100644
--- a/lib/portage/_sets/dbapi.py
+++ b/lib/portage/_sets/dbapi.py
@@ -358,8 +358,7 @@ class AgeSet(EverythingSet):
if ((self._mode == "older" and age <= self._age) \
or (self._mode == "newer" and age >= self._age)):
return False
- else:
- return True
+ return True
def singleBuilder(cls, options, settings, trees):
mode = options.get("mode", "older")
@@ -394,8 +393,7 @@ class DateSet(EverythingSet):
if ((self._mode == "older" and date < self._date) \
or (self._mode == "newer" and date > self._date)):
return True
- else:
- return False
+ return False
def singleBuilder(cls, options, settings, trees):
vardbapi = trees["vartree"].dbapi
@@ -418,9 +416,9 @@ class DateSet(EverythingSet):
elif len(formats) > 1:
raise SetConfigError(_("no more than one of these options is allowed: 'package', 'filestamp', 'seconds', 'date'"))
- format = formats[0]
+ setformat = formats[0]
- if (format == "package"):
+ if (setformat == "package"):
package = options.get("package")
try:
cpv = vardbapi.match(package)[0]
@@ -428,13 +426,13 @@ class DateSet(EverythingSet):
date = int(date)
except (KeyError, ValueError):
raise SetConfigError(_("cannot determine installation date of package %s") % package)
- elif (format == "filestamp"):
+ elif (setformat == "filestamp"):
filestamp = options.get("filestamp")
try:
date = int(os.stat(filestamp).st_mtime)
except (OSError, ValueError):
raise SetConfigError(_("cannot determine 'filestamp' of '%s'") % filestamp)
- elif (format == "seconds"):
+ elif (setformat == "seconds"):
try:
date = int(options.get("seconds"))
except ValueError:
@@ -508,25 +506,24 @@ class ChangedDepsSet(PackageSet):
if isinstance(depatom, list):
# process the nested list.
return [clean_subslots(x, usel) for x in depatom]
- else:
- try:
- # this can be either an atom or some special operator.
- # in the latter case, we get InvalidAtom and pass it as-is.
- a = Atom(depatom)
- except InvalidAtom:
- return depatom
- else:
- # if we're processing portdb, we need to evaluate USE flag
- # dependency conditionals to make them match vdb. this
- # requires passing the list of USE flags, so we reuse it
- # as conditional for the operation as well.
- if usel is not None:
- a = a.evaluate_conditionals(usel)
-
- # replace slot operator := dependencies with plain :=
- # since we can't properly compare expanded slots
- # in vardb to abstract slots in portdb.
- return subslot_repl_re.sub(':=', a)
+
+ try:
+ # this can be either an atom or some special operator.
+ # in the latter case, we get InvalidAtom and pass it as-is.
+ a = Atom(depatom)
+ except InvalidAtom:
+ return depatom
+ # if we're processing portdb, we need to evaluate USE flag
+ # dependency conditionals to make them match vdb. this
+ # requires passing the list of USE flags, so we reuse it
+ # as conditional for the operation as well.
+ if usel is not None:
+ a = a.evaluate_conditionals(usel)
+
+ # replace slot operator := dependencies with plain :=
+ # since we can't properly compare expanded slots
+ # in vardb to abstract slots in portdb.
+ return subslot_repl_re.sub(':=', a)
# get all *DEPEND variables from vdb & portdb and compare them.
# we need to do some cleaning up & expansion to make matching
diff --git a/lib/portage/cache/__init__.py b/lib/portage/cache/__init__.py
index e7fe599f0..e0b8b827f 100644
--- a/lib/portage/cache/__init__.py
+++ b/lib/portage/cache/__init__.py
@@ -1,4 +1,3 @@
# Copyright: 2005 Gentoo Foundation
# Author(s): Brian Harring (ferringb@gentoo.org)
# License: GPL2
-
diff --git a/lib/portage/cache/anydbm.py b/lib/portage/cache/anydbm.py
index 88d85b0da..4cdf264e2 100644
--- a/lib/portage/cache/anydbm.py
+++ b/lib/portage/cache/anydbm.py
@@ -4,32 +4,16 @@
from __future__ import absolute_import
-try:
- import anydbm as anydbm_module
-except ImportError:
- # python 3.x
- import dbm as anydbm_module
+import dbm
try:
import dbm.gnu as gdbm
except ImportError:
- try:
- import gdbm
- except ImportError:
- gdbm = None
+ gdbm = None
-try:
- from dbm import whichdb
-except ImportError:
- from whichdb import whichdb
-
-try:
- import cPickle as pickle
-except ImportError:
- import pickle
+import pickle
from portage import _unicode_encode
from portage import os
-import sys
from portage.cache import fs_template
from portage.cache import cache_errors
@@ -53,15 +37,15 @@ class database(fs_template.FsBased):
self._db_path = os.path.join(self.location, fs_template.gen_label(self.location, self.label)+default_db)
self.__db = None
mode = "w"
- if whichdb(self._db_path) in ("dbm.gnu", "gdbm"):
+ if dbm.whichdb(self._db_path) in ("dbm.gnu", "gdbm"):
# Allow multiple concurrent writers (see bug #53607).
mode += "u"
try:
# dbm.open() will not work with bytes in python-3.1:
# TypeError: can't concat bytes to str
- self.__db = anydbm_module.open(self._db_path,
+ self.__db = dbm.open(self._db_path,
mode, self._perms)
- except anydbm_module.error:
+ except dbm.error:
# XXX handle this at some point
try:
self._ensure_dirs()
@@ -75,14 +59,14 @@ class database(fs_template.FsBased):
# dbm.open() will not work with bytes in python-3.1:
# TypeError: can't concat bytes to str
if gdbm is None:
- self.__db = anydbm_module.open(self._db_path,
+ self.__db = dbm.open(self._db_path,
"c", self._perms)
else:
# Prefer gdbm type if available, since it allows
# multiple concurrent writers (see bug #53607).
self.__db = gdbm.open(self._db_path,
"cu", self._perms)
- except anydbm_module.error as e:
+ except dbm.error as e:
raise cache_errors.InitializationError(self.__class__, e)
self._ensure_access(self._db_path)
@@ -112,5 +96,5 @@ class database(fs_template.FsBased):
self.__db.sync()
self.__db.close()
- if sys.hexversion >= 0x3000000:
- items = iteritems
+ # TODO: do we need iteritems()?
+ items = iteritems
diff --git a/lib/portage/cache/ebuild_xattr.py b/lib/portage/cache/ebuild_xattr.py
index 33a40fdba..6b42d79df 100644
--- a/lib/portage/cache/ebuild_xattr.py
+++ b/lib/portage/cache/ebuild_xattr.py
@@ -38,9 +38,9 @@ class database(fs_template.FsBased):
try:
return int(self.__get(path,'value_max_len'))
except NoValueException as e:
- max = self.__calc_max(path)
- self.__set(path,'value_max_len',str(max))
- return max
+ maxattrlength = self.__calc_max(path)
+ self.__set(path, 'value_max_len', str(maxattrlength))
+ return maxattrlength
def __calc_max(self,path):
""" Find out max attribute length supported by the file system """
@@ -90,8 +90,7 @@ class database(fs_template.FsBased):
except IOError as e:
if not default is None and errno.ENODATA == e.errno:
return default
- else:
- raise NoValueException()
+ raise NoValueException()
def __remove(self,path,key):
xattr.remove(path,key,namespace=self.ns)
@@ -102,48 +101,48 @@ class database(fs_template.FsBased):
def _getitem(self, cpv):
values = {}
path = self.__get_path(cpv)
- all = {}
- for tuple in xattr.get_all(path,namespace=self.ns):
- key,value = tuple
- all[key] = value
+ attrs = {
+ key: value
+ for key, value in xattr.get_all(path, namespace=self.ns)
+ }
if not '_mtime_' in all:
raise KeyError(cpv)
# We default to '' like other caches
for key in self.keys:
- attr_value = all.get(key,'1:')
+ attr_value = attrs.get(key,'1:')
parts,sep,value = attr_value.partition(':')
parts = int(parts)
if parts > 1:
for i in range(1,parts):
- value += all.get(key+str(i))
+ value += attrs.get(key+str(i))
values[key] = value
return values
def _setitem(self, cpv, values):
path = self.__get_path(cpv)
- max = self.max_len
+ max_len = self.max_len
for key,value in values.items():
# mtime comes in as long so need to convert to strings
s = str(value)
# We need to split long values
value_len = len(s)
parts = 0
- if value_len > max:
+ if value_len > max_len:
# Find out how many parts we need
- parts = value_len/max
- if value_len % max > 0:
+ parts = value_len/max_len
+ if value_len % max_len > 0:
parts += 1
# Only the first entry carries the number of parts
- self.__set(path,key,'%s:%s'%(parts,s[0:max]))
+ self.__set(path,key,'%s:%s'%(parts,s[0:max_len]))
# Write out the rest
for i in range(1,parts):
- start = i * max
- val = s[start:start+max]
+ start = i * max_len
+ val = s[start:start+max_len]
self.__set(path,key+str(i),val)
else:
self.__set(path,key,"%s:%s"%(1,s))
diff --git a/lib/portage/cache/flat_hash.py b/lib/portage/cache/flat_hash.py
index 451ea9e51..7d5b44511 100644
--- a/lib/portage/cache/flat_hash.py
+++ b/lib/portage/cache/flat_hash.py
@@ -1,15 +1,12 @@
-# Copyright 2005-2019 Gentoo Authors
+# Copyright 2005-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# Author(s): Brian Harring (ferringb@gentoo.org)
-from __future__ import unicode_literals
-
from portage.cache import fs_template
from portage.cache import cache_errors
import errno
import io
import stat
-import sys
import tempfile
import os as _os
from portage import os
@@ -18,9 +15,6 @@ from portage import _unicode_encode
from portage.exception import InvalidData
from portage.versions import _pkg_str
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- long = int
class database(fs_template.FsBased):
diff --git a/lib/portage/cache/fs_template.py b/lib/portage/cache/fs_template.py
index e3c3c12c2..64050f439 100644
--- a/lib/portage/cache/fs_template.py
+++ b/lib/portage/cache/fs_template.py
@@ -1,9 +1,8 @@
-# Copyright 2005-2014 Gentoo Foundation
+# Copyright 2005-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# Author(s): Brian Harring (ferringb@gentoo.org)
import os as _os
-import sys
from portage.cache import template
from portage import os
@@ -14,9 +13,6 @@ lazyimport(globals(),
)
del lazyimport
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- long = int
class FsBased(template.database):
"""template wrapping fs needed options, and providing _ensure_access as a way to
@@ -44,7 +40,7 @@ class FsBased(template.database):
try:
apply_permissions(path, gid=self._gid, mode=self._perms)
if mtime != -1:
- mtime=long(mtime)
+ mtime=int(mtime)
os.utime(path, (mtime, mtime))
except (PortageException, EnvironmentError):
return False
@@ -59,8 +55,8 @@ class FsBased(template.database):
path = self.location
base='/'
- for dir in path.lstrip(os.path.sep).rstrip(os.path.sep).split(os.path.sep):
- base = os.path.join(base,dir)
+ for d in path.lstrip(os.path.sep).rstrip(os.path.sep).split(os.path.sep):
+ base = os.path.join(base,d)
if ensure_dirs(base):
# We only call apply_permissions if ensure_dirs created
# a new directory, so as not to interfere with
@@ -90,4 +86,3 @@ def gen_label(base, label):
label = os.path.join(*(label.rstrip(os.path.sep).split(os.path.sep)))
tail = os.path.split(label)[1]
return "%s-%X" % (tail, abs(label.__hash__()))
-
diff --git a/lib/portage/cache/index/IndexStreamIterator.py b/lib/portage/cache/index/IndexStreamIterator.py
index 972aee116..4ecfad02b 100644
--- a/lib/portage/cache/index/IndexStreamIterator.py
+++ b/lib/portage/cache/index/IndexStreamIterator.py
@@ -1,7 +1,7 @@
# Copyright 2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-class IndexStreamIterator(object):
+class IndexStreamIterator:
def __init__(self, f, parser):
diff --git a/lib/portage/cache/index/pkg_desc_index.py b/lib/portage/cache/index/pkg_desc_index.py
index dbcbb8313..c3bcbb933 100644
--- a/lib/portage/cache/index/pkg_desc_index.py
+++ b/lib/portage/cache/index/pkg_desc_index.py
@@ -1,22 +1,15 @@
-# Copyright 2014 Gentoo Foundation
+# Copyright 2014-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import collections
-import sys
from portage.versions import _pkg_str
-if sys.hexversion >= 0x3000000:
- _unicode = str
-else:
- _unicode = unicode
pkg_desc_index_node = collections.namedtuple("pkg_desc_index_node",
["cp", "cpv_list", "desc"])
-class pkg_node(_unicode):
+class pkg_node(str):
"""
A minimal package node class. For performance reasons, inputs
are not validated.
@@ -29,7 +22,7 @@ class pkg_node(_unicode):
self.__dict__['build_time'] = None
def __new__(cls, cp, version, repo=None):
- return _unicode.__new__(cls, cp + "-" + version)
+ return str.__new__(cls, cp + "-" + version)
def __setattr__(self, name, value):
raise AttributeError("pkg_node instances are immutable",
diff --git a/lib/portage/cache/mappings.py b/lib/portage/cache/mappings.py
index 0432fdf60..5933981b9 100644
--- a/lib/portage/cache/mappings.py
+++ b/lib/portage/cache/mappings.py
@@ -5,10 +5,9 @@
__all__ = ["Mapping", "MutableMapping", "UserDict", "ProtectedDict",
"LazyLoad", "slot_dict_class"]
-import sys
import weakref
-class Mapping(object):
+class Mapping:
"""
In python-3.0, the UserDict.DictMixin class has been replaced by
Mapping and MutableMapping from the collections module, but 2to3
@@ -25,9 +24,6 @@ class Mapping(object):
def __iter__(self):
return iter(self.keys())
- def keys(self):
- return list(self.__iter__())
-
def __contains__(self, key):
try:
value = self[key]
@@ -46,12 +42,6 @@ class Mapping(object):
for _, v in self.items():
yield v
- def values(self):
- return [v for _, v in self.iteritems()]
-
- def items(self):
- return list(self.iteritems())
-
def get(self, key, default=None):
try:
return self[key]
@@ -64,10 +54,10 @@ class Mapping(object):
def __len__(self):
return len(list(self))
- if sys.hexversion >= 0x3000000:
- items = iteritems
- keys = __iter__
- values = itervalues
+ # TODO: do we need to keep iter*?
+ items = iteritems
+ keys = __iter__
+ values = itervalues
class MutableMapping(Mapping):
"""
@@ -184,8 +174,8 @@ class UserDict(MutableMapping):
def clear(self):
self.data.clear()
- if sys.hexversion >= 0x3000000:
- keys = __iter__
+ keys = __iter__
+
class ProtectedDict(MutableMapping):
"""
@@ -234,8 +224,8 @@ class ProtectedDict(MutableMapping):
def __contains__(self, key):
return key in self.new or (key not in self.blacklist and key in self.orig)
- if sys.hexversion >= 0x3000000:
- keys = __iter__
+ keys = __iter__
+
class LazyLoad(Mapping):
"""
@@ -252,7 +242,7 @@ class LazyLoad(Mapping):
def __getitem__(self, key):
if key in self.d:
return self.d[key]
- elif self.pull != None:
+ if self.pull != None:
self.d.update(self.pull())
self.pull = None
return self.d[key]
@@ -266,13 +256,13 @@ class LazyLoad(Mapping):
def __contains__(self, key):
if key in self.d:
return True
- elif self.pull != None:
+ if self.pull != None:
self.d.update(self.pull())
self.pull = None
return key in self.d
- if sys.hexversion >= 0x3000000:
- keys = __iter__
+ keys = __iter__
+
_slot_dict_classes = weakref.WeakValueDictionary()
@@ -298,7 +288,7 @@ def slot_dict_class(keys, prefix="_val_"):
v = _slot_dict_classes.get((keys_set, prefix))
if v is None:
- class SlotDict(object):
+ class SlotDict:
allowed_keys = keys_set
_prefix = prefix
@@ -328,9 +318,6 @@ def slot_dict_class(keys, prefix="_val_"):
l += 1
return l
- def keys(self):
- return list(self)
-
def iteritems(self):
prefix = self._prefix
for k in self.allowed_keys:
@@ -339,16 +326,10 @@ def slot_dict_class(keys, prefix="_val_"):
except AttributeError:
pass
- def items(self):
- return list(self.iteritems())
-
def itervalues(self):
for k, v in self.iteritems():
yield v
- def values(self):
- return list(self.itervalues())
-
def __delitem__(self, k):
try:
delattr(self, self._prefix + k)
@@ -447,10 +428,9 @@ def slot_dict_class(keys, prefix="_val_"):
def __repr__(self):
return repr(dict(self.iteritems()))
- if sys.hexversion >= 0x3000000:
- items = iteritems
- keys = __iter__
- values = itervalues
+ items = iteritems
+ keys = __iter__
+ values = itervalues
v = SlotDict
_slot_dict_classes[v.allowed_keys] = v
diff --git a/lib/portage/cache/metadata.py b/lib/portage/cache/metadata.py
index 45a057d08..db81b8ba1 100644
--- a/lib/portage/cache/metadata.py
+++ b/lib/portage/cache/metadata.py
@@ -1,11 +1,10 @@
-# Copyright 2005-2018 Gentoo Foundation
+# Copyright 2005-2020 Gentoo Authors
# Author(s): Brian Harring (ferringb@gentoo.org)
# License: GPL2
import errno
import re
import stat
-import sys
from operator import attrgetter
from portage import os
from portage import _encodings
@@ -15,10 +14,6 @@ import portage.eclass_cache
from portage.cache.template import reconstruct_eclasses
from portage.cache.mappings import ProtectedDict
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
- long = int
# this is the old cache format, flat_list. count maintained here.
magic_line_count = 22
@@ -76,7 +71,7 @@ class database(flat_hash.database):
raise cache_errors.CacheCorruption(cpv, e)
else:
d["_eclasses_"] = {}
- elif isinstance(d["_eclasses_"], basestring):
+ elif isinstance(d["_eclasses_"], str):
# We skip this if flat_hash.database._parse_data() was called above
# because it calls reconstruct_eclasses() internally.
d["_eclasses_"] = reconstruct_eclasses(None, d["_eclasses_"])
diff --git a/lib/portage/cache/sql_template.py b/lib/portage/cache/sql_template.py
index d023b1b5d..b87612f2d 100644
--- a/lib/portage/cache/sql_template.py
+++ b/lib/portage/cache/sql_template.py
@@ -2,7 +2,6 @@
# Author(s): Brian Harring (ferringb@gentoo.org)
# License: GPL2
-import sys
from portage.cache import template, cache_errors
from portage.cache.template import reconstruct_eclasses
@@ -296,6 +295,5 @@ class SQLDatabase(template.database):
return [ row[0] for row in self.con.fetchall() ]
- if sys.hexversion >= 0x3000000:
- items = iteritems
- keys = __iter__
+ items = iteritems
+ keys = __iter__
diff --git a/lib/portage/cache/sqlite.py b/lib/portage/cache/sqlite.py
index 69150f679..02bf3fcde 100644
--- a/lib/portage/cache/sqlite.py
+++ b/lib/portage/cache/sqlite.py
@@ -1,10 +1,9 @@
-# Copyright 1999-2014 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import division, unicode_literals
+from __future__ import division
import re
-import sys
from portage.cache import fs_template
from portage.cache import cache_errors
from portage import os
@@ -12,9 +11,6 @@ from portage import _unicode_decode
from portage.util import writemsg
from portage.localization import _
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
class database(fs_template.FsBased):
@@ -64,7 +60,7 @@ class database(fs_template.FsBased):
def _db_escape_string(self, s):
"""meta escaping, returns quoted string for use in sql statements"""
- if not isinstance(s, basestring):
+ if not isinstance(s, str):
# Avoid potential UnicodeEncodeError in python-2.x by
# only calling str() when it's absolutely necessary.
s = str(s)
@@ -267,10 +263,9 @@ class database(fs_template.FsBased):
result = cursor.fetchall()
if len(result) == 0:
return False
- elif len(result) == 1:
+ if len(result) == 1:
return True
- else:
- raise cache_errors.CacheCorruption(cpv, "key is not unique")
+ raise cache_errors.CacheCorruption(cpv, "key is not unique")
def __iter__(self):
"""generator for walking the dir struct"""
diff --git a/lib/portage/cache/template.py b/lib/portage/cache/template.py
index 6b4878347..509f8a2dc 100644
--- a/lib/portage/cache/template.py
+++ b/lib/portage/cache/template.py
@@ -1,23 +1,15 @@
-# Copyright 2005-2014 Gentoo Foundation
+# Copyright 2005-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# Author(s): Brian Harring (ferringb@gentoo.org)
from portage.cache import cache_errors
from portage.cache.cache_errors import InvalidRestriction
from portage.cache.mappings import ProtectedDict
-import sys
import warnings
import operator
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- _unicode = str
- basestring = str
- long = int
-else:
- _unicode = unicode
-class database(object):
+class database:
# this is for metadata/cache transfer.
# basically flags the cache needs be updated when transfered cache to cache.
# leave this.
@@ -94,10 +86,10 @@ class database(object):
d.pop('_mtime_', None)
else:
try:
- mtime = long(mtime)
+ mtime = int(mtime)
except ValueError:
raise cache_errors.CacheCorruption(cpv,
- '_mtime_ conversion to long failed: %s' % (mtime,))
+ '_mtime_ conversion to int failed: %s' % (mtime,))
d['_mtime_'] = mtime
return d
@@ -178,9 +170,6 @@ class database(object):
def has_key(self, cpv):
return cpv in self
- def keys(self):
- return list(self)
-
def iterkeys(self):
return iter(self)
@@ -188,9 +177,6 @@ class database(object):
for x in self:
yield (x, self[x])
- def items(self):
- return list(self.iteritems())
-
def sync(self, rate=0):
self.sync_rate = rate
if(rate == 0):
@@ -278,7 +264,7 @@ class database(object):
for key,match in match_dict.items():
# XXX this sucks.
try:
- if isinstance(match, basestring):
+ if isinstance(match, str):
restricts[key] = re.compile(match).match
else:
restricts[key] = re.compile(match[0],match[1]).match
@@ -297,16 +283,16 @@ class database(object):
if cont:
yield cpv
- if sys.hexversion >= 0x3000000:
- keys = __iter__
- items = iteritems
+ keys = __iter__
+ items = iteritems
+
_keysorter = operator.itemgetter(0)
def serialize_eclasses(eclass_dict, chf_type='mtime', paths=True):
"""takes a dict, returns a string representing said dict"""
"""The "new format", which causes older versions of <portage-2.1.2 to
- traceback with a ValueError due to failed long() conversion. This format
+ traceback with a ValueError due to failed int() conversion. This format
isn't currently written, but the the capability to read it is already built
in.
return "\t".join(["%s\t%s" % (k, str(v)) \
@@ -335,7 +321,7 @@ def _md5_deserializer(md5):
_chf_deserializers = {
'md5': _md5_deserializer,
- 'mtime': long,
+ 'mtime': int,
}
diff --git a/lib/portage/checksum.py b/lib/portage/checksum.py
index 4174638e6..8f01f6ac4 100644
--- a/lib/portage/checksum.py
+++ b/lib/portage/checksum.py
@@ -12,7 +12,6 @@ import errno
import functools
import hashlib
import stat
-import sys
import subprocess
import tempfile
@@ -52,7 +51,7 @@ def _open_file(filename):
else:
raise
-class _generate_hash_function(object):
+class _generate_hash_function:
__slots__ = ("_hashobject",)
@@ -159,7 +158,7 @@ if False:
import binascii
import pygcrypt.hashcontext
- class GCryptHashWrapper(object):
+ class GCryptHashWrapper:
def __init__(self, algo):
self._obj = pygcrypt.hashcontext.HashContext(algo=algo,
secure=False)
@@ -287,7 +286,7 @@ if "WHIRLPOOL" not in hashfunc_map:
# There is only one implementation for size
-class SizeHash(object):
+class SizeHash:
def checksum_file(self, filename):
size = os.stat(filename).st_size
return (size, size)
@@ -361,7 +360,7 @@ def _filter_unaccelarated_hashes(digests):
return digests
-class _hash_filter(object):
+class _hash_filter:
"""
Implements filtering for PORTAGE_CHECKSUM_FILTER.
"""
@@ -383,7 +382,7 @@ class _hash_filter(object):
for token in self._tokens:
if token in matches:
return True
- elif token[:1] == "-":
+ if token[:1] == "-":
if token[1:] in matches:
return False
return False
diff --git a/lib/portage/const.py b/lib/portage/const.py
index 146808fea..50412c058 100644
--- a/lib/portage/const.py
+++ b/lib/portage/const.py
@@ -2,8 +2,6 @@
# Copyright 1998-2019 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
# ===========================================================================
# autotool supplied constants.
# ===========================================================================
diff --git a/lib/portage/cvstree.py b/lib/portage/cvstree.py
index 87bbed8bb..796462af2 100644
--- a/lib/portage/cvstree.py
+++ b/lib/portage/cvstree.py
@@ -7,16 +7,12 @@ from __future__ import print_function
import io
import re
import stat
-import sys
import time
from portage import os
from portage import _encodings
from portage import _unicode_encode
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- long = int
# [D]/Name/Version/Date/Flags/Tags
@@ -33,10 +29,9 @@ def pathdata(entries, path):
return None
if mytarget in myentries["dirs"]:
return myentries["dirs"][mytarget]
- elif mytarget in myentries["files"]:
+ if mytarget in myentries["files"]:
return myentries["files"][mytarget]
- else:
- return None
+ return None
def fileat(entries, path):
return pathdata(entries, path)
@@ -202,14 +197,14 @@ def findall(entries, recursive=0, basedir=""):
return [mynew, mychanged, mymissing, myunadded, myremoved]
ignore_list = re.compile(r"(^|/)(RCS(|LOG)|SCCS|CVS(|\.adm)|cvslog\..*|tags|TAGS|\.(make\.state|nse_depinfo)|.*~|(\.|)#.*|,.*|_$.*|.*\$|\.del-.*|.*\.(old|BAK|bak|orig|rej|a|olb|o|obj|so|exe|Z|elc|ln)|core)$")
-def apply_cvsignore_filter(list):
+def apply_cvsignore_filter(files):
x = 0
- while x < len(list):
- if ignore_list.match(list[x].split("/")[-1]):
- list.pop(x)
+ while x < len(files):
+ if ignore_list.match(files[x].split("/")[-1]):
+ files.pop(x)
else:
x += 1
- return list
+ return files
def getentries(mydir, recursive=0):
"""Scans the given directory and returns a datadict of all the entries in
diff --git a/lib/portage/data.py b/lib/portage/data.py
index 20a8d1ba7..d2d356f95 100644
--- a/lib/portage/data.py
+++ b/lib/portage/data.py
@@ -2,7 +2,10 @@
# Copyright 1998-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-import os, pwd, grp, platform, sys
+import grp
+import os
+import platform
+import pwd
from portage.const import PORTAGE_GROUPNAME, PORTAGE_USERNAME, EPREFIX
import portage
@@ -198,10 +201,9 @@ def _get_global(k):
if k == 'portage_gid':
return portage_gid
- elif k == 'portage_uid':
+ if k == 'portage_uid':
return portage_uid
- else:
- raise AssertionError('unknown name: %s' % k)
+ raise AssertionError('unknown name: %s' % k)
elif k == 'userpriv_groups':
v = [_get_global('portage_gid')]
diff --git a/lib/portage/dbapi/DummyTree.py b/lib/portage/dbapi/DummyTree.py
index 6579e88e2..5ad7389d4 100644
--- a/lib/portage/dbapi/DummyTree.py
+++ b/lib/portage/dbapi/DummyTree.py
@@ -1,7 +1,7 @@
# Copyright 2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-class DummyTree(object):
+class DummyTree:
"""
Most internal code only accesses the "dbapi" attribute of the
binarytree, portagetree, and vartree classes. DummyTree is useful
diff --git a/lib/portage/dbapi/IndexedPortdb.py b/lib/portage/dbapi/IndexedPortdb.py
index 510e0278c..5f1cb5bd1 100644
--- a/lib/portage/dbapi/IndexedPortdb.py
+++ b/lib/portage/dbapi/IndexedPortdb.py
@@ -17,7 +17,7 @@ from portage.cache.index.pkg_desc_index import \
from portage.util.iterators.MultiIterGroupBy import MultiIterGroupBy
from portage.versions import _pkg_str
-class IndexedPortdb(object):
+class IndexedPortdb:
"""
A portdbapi interface that uses a package description index to
improve performance. If the description index is missing for a
@@ -90,7 +90,7 @@ class IndexedPortdb(object):
if index_missing:
self._unindexed_cp_map = {}
- class _NonIndexedStream(object):
+ class _NonIndexedStream:
def __iter__(self_):
for cp in self._portdb.cp_all(
trees = index_missing):
@@ -159,8 +159,7 @@ class IndexedPortdb(object):
if atom == atom.cp:
return cp_list[:]
- else:
- return portage.match_from_list(atom, cp_list)
+ return portage.match_from_list(atom, cp_list)
def aux_get(self, cpv, attrs, myrepo=None):
if len(attrs) == 1 and attrs[0] == "DESCRIPTION":
diff --git a/lib/portage/dbapi/IndexedVardb.py b/lib/portage/dbapi/IndexedVardb.py
index e2910b27f..a04e3074c 100644
--- a/lib/portage/dbapi/IndexedVardb.py
+++ b/lib/portage/dbapi/IndexedVardb.py
@@ -6,7 +6,7 @@ from portage.dep import Atom
from portage.exception import InvalidData
from portage.versions import _pkg_str
-class IndexedVardb(object):
+class IndexedVardb:
"""
A vardbapi interface that sacrifices validation in order to
improve performance. It takes advantage of vardbdbapi._aux_cache,
@@ -97,8 +97,7 @@ class IndexedVardb(object):
if atom == atom.cp:
return cp_list[:]
- else:
- return portage.match_from_list(atom, cp_list)
+ return portage.match_from_list(atom, cp_list)
def aux_get(self, cpv, attrs, myrepo=None):
pkg_data = self._vardb._aux_cache["packages"].get(cpv)
diff --git a/lib/portage/dbapi/_ContentsCaseSensitivityManager.py b/lib/portage/dbapi/_ContentsCaseSensitivityManager.py
index c479ec971..465d80554 100644
--- a/lib/portage/dbapi/_ContentsCaseSensitivityManager.py
+++ b/lib/portage/dbapi/_ContentsCaseSensitivityManager.py
@@ -1,7 +1,7 @@
# Copyright 2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-class ContentsCaseSensitivityManager(object):
+class ContentsCaseSensitivityManager:
"""
Implicitly handles case transformations that are needed for
case-insensitive support.
diff --git a/lib/portage/dbapi/_MergeProcess.py b/lib/portage/dbapi/_MergeProcess.py
index 371550079..e89b53555 100644
--- a/lib/portage/dbapi/_MergeProcess.py
+++ b/lib/portage/dbapi/_MergeProcess.py
@@ -1,11 +1,8 @@
-# Copyright 2010-2018 Gentoo Foundation
+# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import io
import platform
-import signal
-import sys
-import traceback
import fcntl
import portage
@@ -24,7 +21,7 @@ class MergeProcess(ForkProcess):
'vartree', 'blockers', 'pkgloc', 'infloc', 'myebuild',
'mydbapi', 'postinst_failure', 'prev_mtimes', 'unmerge',
'_elog_reader_fd',
- '_buf', '_elog_keys', '_locked_vdb')
+ '_buf', '_counter', '_dblink', '_elog_keys', '_locked_vdb')
def _start(self):
# Portage should always call setcpv prior to this
@@ -57,6 +54,7 @@ class MergeProcess(ForkProcess):
self.fd_pipes = self.fd_pipes.copy()
self.fd_pipes.setdefault(0, portage._get_stdin().fileno())
+ self.log_filter_file = self.settings.get('PORTAGE_LOG_FILTER_FILE_CMD')
super(MergeProcess, self)._start()
def _lock_vdb(self):
@@ -102,8 +100,8 @@ class MergeProcess(ForkProcess):
def _spawn(self, args, fd_pipes, **kwargs):
"""
- Fork a subprocess, apply local settings, and call
- dblink.merge(). TODO: Share code with ForkProcess.
+ Extend the superclass _spawn method to perform some pre-fork and
+ post-fork actions.
"""
elog_reader_fd, elog_writer_fd = os.pipe()
@@ -111,16 +109,6 @@ class MergeProcess(ForkProcess):
fcntl.fcntl(elog_reader_fd, fcntl.F_SETFL,
fcntl.fcntl(elog_reader_fd, fcntl.F_GETFL) | os.O_NONBLOCK)
- # FD_CLOEXEC is enabled by default in Python >=3.4.
- if sys.hexversion < 0x3040000:
- try:
- fcntl.FD_CLOEXEC
- except AttributeError:
- pass
- else:
- fcntl.fcntl(elog_reader_fd, fcntl.F_SETFD,
- fcntl.fcntl(elog_reader_fd, fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
-
blockers = None
if self.blockers is not None:
# Query blockers in the main process, since closing
@@ -141,57 +129,31 @@ class MergeProcess(ForkProcess):
# FEATURES=parallel-install skips this lock in order to
# improve performance, and the risk is practically negligible.
self._lock_vdb()
- counter = None
if not self.unmerge:
- counter = self.vartree.dbapi.counter_tick()
-
- parent_pid = os.getpid()
- pid = None
- try:
- pid = os.fork()
-
- if pid != 0:
- if not isinstance(pid, int):
- raise AssertionError(
- "fork returned non-integer: %s" % (repr(pid),))
-
- os.close(elog_writer_fd)
- self._elog_reader_fd = elog_reader_fd
- self._buf = ""
- self._elog_keys = set()
- # Discard messages which will be collected by the subprocess,
- # in order to avoid duplicates (bug #446136).
- portage.elog.messages.collect_messages(key=mylink.mycpv)
-
- # invalidate relevant vardbapi caches
- if self.vartree.dbapi._categories is not None:
- self.vartree.dbapi._categories = None
- self.vartree.dbapi._pkgs_changed = True
- self.vartree.dbapi._clear_pkg_cache(mylink)
-
- return [pid]
-
- os.close(elog_reader_fd)
-
- # Use default signal handlers in order to avoid problems
- # killing subprocesses as reported in bug #353239.
- signal.signal(signal.SIGINT, signal.SIG_DFL)
- signal.signal(signal.SIGTERM, signal.SIG_DFL)
-
- # Unregister SIGCHLD handler and wakeup_fd for the parent
- # process's event loop (bug 655656).
- signal.signal(signal.SIGCHLD, signal.SIG_DFL)
- try:
- wakeup_fd = signal.set_wakeup_fd(-1)
- if wakeup_fd > 0:
- os.close(wakeup_fd)
- except (ValueError, OSError):
- pass
-
- portage.locks._close_fds()
- # We don't exec, so use close_fds=False
- # (see _setup_pipes docstring).
- portage.process._setup_pipes(fd_pipes, close_fds=False)
+ self._counter = self.vartree.dbapi.counter_tick()
+
+ self._dblink = mylink
+ self._elog_reader_fd = elog_reader_fd
+ pids = super(MergeProcess, self)._spawn(args, fd_pipes, **kwargs)
+ os.close(elog_writer_fd)
+ self._buf = ""
+ self._elog_keys = set()
+ # Discard messages which will be collected by the subprocess,
+ # in order to avoid duplicates (bug #446136).
+ portage.elog.messages.collect_messages(key=mylink.mycpv)
+
+ # invalidate relevant vardbapi caches
+ if self.vartree.dbapi._categories is not None:
+ self.vartree.dbapi._categories = None
+ self.vartree.dbapi._pkgs_changed = True
+ self.vartree.dbapi._clear_pkg_cache(mylink)
+
+ return pids
+
+ def _run(self):
+ os.close(self._elog_reader_fd)
+ counter = self._counter
+ mylink = self._dblink
portage.output.havecolor = self.settings.get('NOCOLOR') \
not in ('yes', 'true')
@@ -216,8 +178,7 @@ class MergeProcess(ForkProcess):
self.settings.backup_changes("PORTAGE_BACKGROUND")
rval = 1
- try:
- if self.unmerge:
+ if self.unmerge:
if not mylink.exists():
rval = os.EX_OK
elif mylink.unmerge(
@@ -228,37 +189,20 @@ class MergeProcess(ForkProcess):
finally:
mylink.unlockdb()
rval = os.EX_OK
- else:
+ else:
rval = mylink.merge(self.pkgloc, self.infloc,
myebuild=self.myebuild, mydbapi=self.mydbapi,
prev_mtimes=self.prev_mtimes, counter=counter)
- except SystemExit:
- raise
- except:
- traceback.print_exc()
- # os._exit() skips stderr flush!
- sys.stderr.flush()
- finally:
- os._exit(rval)
-
- finally:
- if pid == 0 or (pid is None and os.getpid() != parent_pid):
- # Call os._exit() from a finally block in order
- # to suppress any finally blocks from earlier
- # in the call stack (see bug #345289). This
- # finally block has to be setup before the fork
- # in order to avoid a race condition.
- os._exit(1)
+ return rval
- def _async_waitpid_cb(self, *args, **kwargs):
+ def _proc_join_done(self, proc, future):
"""
- Override _async_waitpid_cb to perform cleanup that is
- not necessarily idempotent.
+ Extend _proc_join_done to react to RETURNCODE_POSTINST_FAILURE.
"""
- ForkProcess._async_waitpid_cb(self, *args, **kwargs)
- if self.returncode == portage.const.RETURNCODE_POSTINST_FAILURE:
+ if not future.cancelled() and proc.exitcode == portage.const.RETURNCODE_POSTINST_FAILURE:
self.postinst_failure = True
self.returncode = os.EX_OK
+ super(MergeProcess, self)._proc_join_done(proc, future)
def _unregister(self):
"""
diff --git a/lib/portage/dbapi/_VdbMetadataDelta.py b/lib/portage/dbapi/_VdbMetadataDelta.py
index 7461f87c5..ffdc0b361 100644
--- a/lib/portage/dbapi/_VdbMetadataDelta.py
+++ b/lib/portage/dbapi/_VdbMetadataDelta.py
@@ -10,7 +10,7 @@ from portage import _encodings
from portage.util import atomic_ofstream
from portage.versions import cpv_getkey
-class VdbMetadataDelta(object):
+class VdbMetadataDelta:
_format_version = "1"
diff --git a/lib/portage/dbapi/__init__.py b/lib/portage/dbapi/__init__.py
index 37728714e..bea5a82cb 100644
--- a/lib/portage/dbapi/__init__.py
+++ b/lib/portage/dbapi/__init__.py
@@ -1,8 +1,6 @@
# Copyright 1998-2019 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
__all__ = ["dbapi"]
import functools
@@ -26,7 +24,7 @@ from portage.exception import InvalidData
from portage.localization import _
from _emerge.Package import Package
-class dbapi(object):
+class dbapi:
_category_re = re.compile(r'^\w[-.+\w]*$', re.UNICODE)
_categories = None
_use_mutable = False
diff --git a/lib/portage/dbapi/_expand_new_virt.py b/lib/portage/dbapi/_expand_new_virt.py
index 9aa603d11..0edfb2ae2 100644
--- a/lib/portage/dbapi/_expand_new_virt.py
+++ b/lib/portage/dbapi/_expand_new_virt.py
@@ -1,8 +1,6 @@
# Copyright 2011-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import portage
from portage.dep import Atom, _get_useflag_re
from portage.eapi import _get_eapi_attrs
diff --git a/lib/portage/dbapi/bintree.py b/lib/portage/dbapi/bintree.py
index 2f6c4f343..9111cec06 100644
--- a/lib/portage/dbapi/bintree.py
+++ b/lib/portage/dbapi/bintree.py
@@ -1,8 +1,6 @@
-# Copyright 1998-2019 Gentoo Authors
+# Copyright 1998-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
__all__ = ["bindbapi", "binarytree"]
import portage
@@ -46,7 +44,6 @@ import errno
import io
import stat
import subprocess
-import sys
import tempfile
import textwrap
import time
@@ -54,18 +51,8 @@ import traceback
import warnings
from gzip import GzipFile
from itertools import chain
-try:
- from urllib.parse import urlparse
-except ImportError:
- from urlparse import urlparse
-
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- _unicode = str
- basestring = str
- long = int
-else:
- _unicode = unicode
+from urllib.parse import urlparse
+
class UseCachedCopyOfRemoteIndex(Exception):
# If the local copy is recent enough
@@ -152,7 +139,7 @@ class bindbapi(fakedbapi):
add_pkg = self.bintree._additional_pkgs.get(instance_key)
if add_pkg is not None:
return add_pkg._db.aux_get(add_pkg, wants)
- elif not self.bintree._remotepkgs or \
+ if not self.bintree._remotepkgs or \
not self.bintree.isremote(mycpv):
try:
tbz2_path = self.bintree._pkg_paths[instance_key]
@@ -166,9 +153,9 @@ class bindbapi(fakedbapi):
metadata_bytes = portage.xpak.tbz2(tbz2_path).get_data()
def getitem(k):
if k == "_mtime_":
- return _unicode(st[stat.ST_MTIME])
- elif k == "SIZE":
- return _unicode(st.st_size)
+ return str(st[stat.ST_MTIME])
+ if k == "SIZE":
+ return str(st.st_size)
v = metadata_bytes.get(_unicode_encode(k,
encoding=_encodings['repo.content'],
errors='backslashreplace'))
@@ -339,7 +326,7 @@ class bindbapi(fakedbapi):
return filesdict
-class binarytree(object):
+class binarytree:
"this tree scans for a list of all packages available in PKGDIR"
def __init__(self, _unused=DeprecationWarning, pkgdir=None,
virtual=DeprecationWarning, settings=None):
@@ -471,7 +458,7 @@ class binarytree(object):
# sanity check
for atom in (origcp, newcp):
if not isjustname(atom):
- raise InvalidPackageName(_unicode(atom))
+ raise InvalidPackageName(str(atom))
mynewcat = catsplit(newcp)[0]
origmatches=self.dbapi.cp_list(origcp)
moves = 0
@@ -495,7 +482,7 @@ class binarytree(object):
if not isvalidatom(newcp, eapi=mycpv.eapi):
continue
- mynewcpv = mycpv.replace(mycpv_cp, _unicode(newcp), 1)
+ mynewcpv = mycpv.replace(mycpv_cp, str(newcp), 1)
myoldpkg = catsplit(mycpv)[1]
mynewpkg = catsplit(mynewcpv)[1]
@@ -728,12 +715,12 @@ class binarytree(object):
match = None
for d in possibilities:
try:
- if long(d["_mtime_"]) != s[stat.ST_MTIME]:
+ if int(d["_mtime_"]) != s[stat.ST_MTIME]:
continue
except (KeyError, ValueError):
continue
try:
- if long(d["SIZE"]) != long(s.st_size):
+ if int(d["SIZE"]) != int(s.st_size):
continue
except (KeyError, ValueError):
continue
@@ -820,7 +807,7 @@ class binarytree(object):
if pkg_metadata.get("BUILD_ID"):
try:
- build_id = long(pkg_metadata["BUILD_ID"])
+ build_id = int(pkg_metadata["BUILD_ID"])
except ValueError:
writemsg(_("!!! Binary package has "
"invalid BUILD_ID: '%s'\n") %
@@ -850,8 +837,8 @@ class binarytree(object):
noiselevel=-1)
continue
if build_id is not None:
- pkg_metadata["BUILD_ID"] = _unicode(build_id)
- pkg_metadata["SIZE"] = _unicode(s.st_size)
+ pkg_metadata["BUILD_ID"] = str(build_id)
+ pkg_metadata["SIZE"] = str(s.st_size)
# Discard items used only for validation above.
pkg_metadata.pop("CATEGORY")
pkg_metadata.pop("PF")
@@ -865,13 +852,13 @@ class binarytree(object):
pkgindex._pkg_slot_dict())
if d:
try:
- if long(d["_mtime_"]) != s[stat.ST_MTIME]:
+ if int(d["_mtime_"]) != s[stat.ST_MTIME]:
d.clear()
except (KeyError, ValueError):
d.clear()
if d:
try:
- if long(d["SIZE"]) != long(s.st_size):
+ if int(d["SIZE"]) != int(s.st_size):
d.clear()
except (KeyError, ValueError):
d.clear()
@@ -1097,12 +1084,12 @@ class binarytree(object):
writemsg(_("\n\n!!! Error fetching binhost package" \
" info from '%s'\n") % _hide_url_passwd(base_url))
# With Python 2, the EnvironmentError message may
- # contain bytes or unicode, so use _unicode to ensure
+ # contain bytes or unicode, so use str to ensure
# safety with all locales (bug #532784).
try:
- error_msg = _unicode(e)
+ error_msg = str(e)
except UnicodeDecodeError as uerror:
- error_msg = _unicode(uerror.object,
+ error_msg = str(uerror.object,
encoding='utf_8', errors='replace')
writemsg("!!! %s\n\n" % error_msg)
del e
@@ -1245,7 +1232,7 @@ class binarytree(object):
# attributes, so that we can later distinguish that it
# is identical to its remote counterpart.
build_id = self._parse_build_id(basename)
- metadata["BUILD_ID"] = _unicode(build_id)
+ metadata["BUILD_ID"] = str(build_id)
cpv = _pkg_str(cpv, metadata=metadata,
settings=self.settings, db=self.dbapi)
binpkg = portage.xpak.tbz2(full_path)
@@ -1297,9 +1284,9 @@ class binarytree(object):
binary_metadata = portage.xpak.tbz2(filename).get_data()
for k in keys:
if k == "_mtime_":
- metadata[k] = _unicode(st[stat.ST_MTIME])
+ metadata[k] = str(st[stat.ST_MTIME])
elif k == "SIZE":
- metadata[k] = _unicode(st.st_size)
+ metadata[k] = str(st.st_size)
else:
v = binary_metadata.get(_unicode_encode(k))
if v is None:
@@ -1357,7 +1344,7 @@ class binarytree(object):
contents = codecs.getwriter(_encodings['repo.content'])(io.BytesIO())
pkgindex.write(contents)
contents = contents.getvalue()
- atime = mtime = long(pkgindex.header["TIMESTAMP"])
+ atime = mtime = int(pkgindex.header["TIMESTAMP"])
output_files = [(atomic_ofstream(self._pkgindex_file, mode="wb"),
self._pkgindex_file, None)]
@@ -1392,8 +1379,8 @@ class binarytree(object):
d["CPV"] = cpv
st = os.lstat(pkg_path)
- d["_mtime_"] = _unicode(st[stat.ST_MTIME])
- d["SIZE"] = _unicode(st.st_size)
+ d["_mtime_"] = str(st[stat.ST_MTIME])
+ d["SIZE"] = str(st.st_size)
rel_path = pkg_path[len(self.pkgdir)+1:]
# record location if it's non-default
@@ -1472,7 +1459,7 @@ class binarytree(object):
"""
if not (self.settings.profile_path and
"IUSE_IMPLICIT" in self.settings):
- header.setdefault("VERSION", _unicode(self._pkgindex_version))
+ header.setdefault("VERSION", str(self._pkgindex_version))
return
portdir = normalize_path(os.path.realpath(self.settings["PORTDIR"]))
@@ -1483,7 +1470,7 @@ class binarytree(object):
if profile_path.startswith(profiles_base):
profile_path = profile_path[len(profiles_base):]
header["PROFILE"] = profile_path
- header["VERSION"] = _unicode(self._pkgindex_version)
+ header["VERSION"] = str(self._pkgindex_version)
base_uri = self.settings.get("PORTAGE_BINHOST_HEADER_URI")
if base_uri:
header["URI"] = base_uri
@@ -1658,7 +1645,7 @@ class binarytree(object):
if hyphen != -1:
build_id = filename[hyphen+1:-suffixlen]
try:
- build_id = long(build_id)
+ build_id = int(build_id)
except ValueError:
pass
return build_id
@@ -1671,7 +1658,7 @@ class binarytree(object):
instance_key = self.dbapi._instance_key(pkgname)
if instance_key not in self._remotepkgs:
return False
- elif instance_key in self._additional_pkgs:
+ if instance_key in self._additional_pkgs:
return False
# Presence in self._remotepkgs implies that it's remote. When a
# package is downloaded, state is updated by self.inject().
@@ -1696,10 +1683,10 @@ class binarytree(object):
if os.path.exists(tbz2_path):
if tbz2name[:-5] not in self.invalids:
return
- else:
- resume = True
- writemsg(_("Resuming download of this tbz2, but it is possible that it is corrupt.\n"),
- noiselevel=-1)
+
+ resume = True
+ writemsg(_("Resuming download of this tbz2, but it is possible that it is corrupt.\n"),
+ noiselevel=-1)
mydest = os.path.dirname(self.getname(pkgname))
self._ensure_dir(mydest)
diff --git a/lib/portage/dbapi/cpv_expand.py b/lib/portage/dbapi/cpv_expand.py
index ac2f6cc2e..a1a91f554 100644
--- a/lib/portage/dbapi/cpv_expand.py
+++ b/lib/portage/dbapi/cpv_expand.py
@@ -1,8 +1,6 @@
# Copyright 2010-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
__all__ = ["cpv_expand"]
import portage
@@ -102,7 +100,5 @@ def cpv_expand(mycpv, mydb=None, use_cache=1, settings=None):
if mysplit:
if mysplit[2]=="r0":
return mykey+"-"+mysplit[1]
- else:
- return mykey+"-"+mysplit[1]+"-"+mysplit[2]
- else:
- return mykey
+ return mykey+"-"+mysplit[1]+"-"+mysplit[2]
+ return mykey
diff --git a/lib/portage/dbapi/dep_expand.py b/lib/portage/dbapi/dep_expand.py
index 9515b7dec..fab5fa830 100644
--- a/lib/portage/dbapi/dep_expand.py
+++ b/lib/portage/dbapi/dep_expand.py
@@ -1,8 +1,6 @@
# Copyright 2010-2018 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
__all__ = ["dep_expand"]
import re
diff --git a/lib/portage/dbapi/porttree.py b/lib/portage/dbapi/porttree.py
index 08af17bcd..4b714a919 100644
--- a/lib/portage/dbapi/porttree.py
+++ b/lib/portage/dbapi/porttree.py
@@ -1,8 +1,6 @@
# Copyright 1998-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
__all__ = [
"close_portdbapi_caches", "FetchlistDict", "portagetree", "portdbapi"
]
@@ -41,7 +39,6 @@ from portage.util.futures.iter_completed import iter_gather
from _emerge.EbuildMetadataPhase import EbuildMetadataPhase
import os as _os
-import sys
import traceback
import warnings
import errno
@@ -49,16 +46,8 @@ import collections
import functools
from collections import OrderedDict
+from urllib.parse import urlparse
-try:
- from urllib.parse import urlparse
-except ImportError:
- from urlparse import urlparse
-
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
- long = int
def close_portdbapi_caches():
# The python interpreter does _not_ guarantee that destructors are
@@ -108,7 +97,7 @@ class _dummy_list(list):
pass
-class _better_cache(object):
+class _better_cache:
"""
The purpose of better_cache is to locate catpkgs in repositories using ``os.listdir()`` as much as possible, which
@@ -164,8 +153,13 @@ class _better_cache(object):
raise
continue
for p in pkg_list:
- if os.path.isdir(cat_dir + "/" + p):
- self._items[cat + "/" + p].append(repo)
+ try:
+ atom = Atom("%s/%s" % (cat, p))
+ except InvalidAtom:
+ continue
+ if atom != atom.cp:
+ continue
+ self._items[atom.cp].append(repo)
self._scanned_cats.add(cat)
@@ -883,7 +877,7 @@ class portdbapi(dbapi):
filesdict[myfile] = int(checksums[myfile]["size"])
return filesdict
- def fetch_check(self, mypkg, useflags=None, mysettings=None, all=False, myrepo=None):
+ def fetch_check(self, mypkg, useflags=None, mysettings=None, all=False, myrepo=None): # pylint: disable=redefined-builtin
"""
TODO: account for PORTAGE_RO_DISTDIRS
"""
@@ -936,8 +930,7 @@ class portdbapi(dbapi):
return 0
if self.findname(cps[0] + "/" + cps2[1], myrepo=myrepo):
return 1
- else:
- return 0
+ return 0
def cp_all(self, categories=None, trees=None, reverse=False, sort=True):
"""
@@ -994,7 +987,7 @@ class portdbapi(dbapi):
# stable sort by version produces results ordered by
# (pkg.version, repo.priority).
if mytree is not None:
- if isinstance(mytree, basestring):
+ if isinstance(mytree, str):
repos = [self.repositories.get_repo_for_location(mytree)]
else:
# assume it's iterable
@@ -1316,7 +1309,7 @@ class portdbapi(dbapi):
return True
-class portagetree(object):
+class portagetree:
def __init__(self, root=DeprecationWarning, virtual=DeprecationWarning,
settings=None):
"""
@@ -1456,12 +1449,7 @@ class FetchlistDict(Mapping):
infinite recursion in some cases."""
return len(self.portdb.cp_list(self.cp, mytree=self.mytree))
- def keys(self):
- """Returns keys for all packages within pkgdir"""
- return self.portdb.cp_list(self.cp, mytree=self.mytree)
-
- if sys.hexversion >= 0x3000000:
- keys = __iter__
+ keys = __iter__
def _async_manifest_fetchlist(portdb, repo_config, cp, cpv_list=None,
@@ -1508,7 +1496,7 @@ def _async_manifest_fetchlist(portdb, repo_config, cp, cpv_list=None,
if result.cancelled():
return
- elif e is None:
+ if e is None:
result.set_result(dict((k, list(v.result()))
for k, v in zip(cpv_list, gather_result.result())))
else:
diff --git a/lib/portage/dbapi/vartree.py b/lib/portage/dbapi/vartree.py
index d7c8ef3de..4a45a3169 100644
--- a/lib/portage/dbapi/vartree.py
+++ b/lib/portage/dbapi/vartree.py
@@ -1,7 +1,7 @@
-# Copyright 1998-2019 Gentoo Authors
+# Copyright 1998-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import division, unicode_literals
+from __future__ import division
__all__ = [
"vardbapi", "vartree", "dblink"] + \
@@ -36,7 +36,6 @@ portage.proxy.lazyimport.lazyimport(globals(),
'portage.util.install_mask:install_mask_dir,InstallMask,_raise_exc',
'portage.util.listdir:dircache,listdir',
'portage.util.movefile:movefile',
- 'portage.util.monotonic:monotonic',
'portage.util.path:first_existing,iter_parents',
'portage.util.writeable_check:get_ro_checker',
'portage.util._xattr:xattr',
@@ -96,28 +95,16 @@ from itertools import chain
import logging
import os as _os
import operator
+import pickle
import platform
import pwd
import re
import stat
-import sys
import tempfile
import textwrap
import time
import warnings
-try:
- import cPickle as pickle
-except ImportError:
- import pickle
-
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
- long = int
- _unicode = str
-else:
- _unicode = unicode
class vardbapi(dbapi):
@@ -366,7 +353,7 @@ class vardbapi(dbapi):
def cpv_counter(self, mycpv):
"This method will grab the COUNTER. Returns a counter value."
try:
- return long(self.aux_get(mycpv, ["COUNTER"])[0])
+ return int(self.aux_get(mycpv, ["COUNTER"])[0])
except (KeyError, ValueError):
pass
writemsg_level(_("portage: COUNTER for %s was corrupted; " \
@@ -419,7 +406,7 @@ class vardbapi(dbapi):
if not isvalidatom(newcp, eapi=mycpv.eapi):
continue
- mynewcpv = mycpv.replace(mycpv_cp, _unicode(newcp), 1)
+ mynewcpv = mycpv.replace(mycpv_cp, str(newcp), 1)
mynewcat = catsplit(newcp)[0]
origpath = self.getpath(mycpv)
if not os.path.exists(origpath):
@@ -457,10 +444,7 @@ class vardbapi(dbapi):
if mysplit[0] == '*':
mysplit[0] = mysplit[0][1:]
try:
- if sys.hexversion >= 0x3030000:
- mystat = os.stat(self.getpath(mysplit[0])).st_mtime_ns
- else:
- mystat = os.stat(self.getpath(mysplit[0])).st_mtime
+ mystat = os.stat(self.getpath(mysplit[0])).st_mtime_ns
except OSError:
mystat = 0
if use_cache and mycp in self.cpcache:
@@ -608,10 +592,7 @@ class vardbapi(dbapi):
return list(self._iter_match(mydep,
self.cp_list(mydep.cp, use_cache=use_cache)))
try:
- if sys.hexversion >= 0x3030000:
- curmtime = os.stat(os.path.join(self._eroot, VDB_PATH, mycat)).st_mtime_ns
- else:
- curmtime = os.stat(os.path.join(self._eroot, VDB_PATH, mycat)).st_mtime
+ curmtime = os.stat(os.path.join(self._eroot, VDB_PATH, mycat)).st_mtime_ns
except (IOError, OSError):
curmtime=0
@@ -774,7 +755,7 @@ class vardbapi(dbapi):
pkg_data = None
else:
cache_mtime, metadata = pkg_data
- if not isinstance(cache_mtime, (float, long, int)) or \
+ if not isinstance(cache_mtime, (float, int)) or \
not isinstance(metadata, dict):
pkg_data = None
@@ -786,7 +767,7 @@ class vardbapi(dbapi):
# Handle truncated mtime in order to avoid cache
# invalidation for livecd squashfs (bug 564222).
- elif long(cache_mtime) == mydir_stat.st_mtime:
+ elif int(cache_mtime) == mydir_stat.st_mtime:
cache_valid = True
else:
# Cache may contain integer mtime.
@@ -811,7 +792,7 @@ class vardbapi(dbapi):
cache_data.update(metadata)
for aux_key in cache_these:
cache_data[aux_key] = mydata[aux_key]
- self._aux_cache["packages"][_unicode(mycpv)] = \
+ self._aux_cache["packages"][str(mycpv)] = \
(mydir_mtime, cache_data)
self._aux_cache["modified"].add(mycpv)
@@ -1105,7 +1086,7 @@ class vardbapi(dbapi):
mode='r', encoding=_encodings['repo.content'],
errors='replace') as f:
try:
- counter = long(f.readline().strip())
+ counter = int(f.readline().strip())
except (OverflowError, ValueError) as e:
writemsg(_("!!! COUNTER file is corrupt: '%s'\n") %
self._counter_path, noiselevel=-1)
@@ -1264,7 +1245,7 @@ class vardbapi(dbapi):
if new_needed is not None:
f = atomic_ofstream(os.path.join(pkg.dbdir, LinkageMap._needed_aux_key))
for entry in new_needed:
- f.write(_unicode(entry))
+ f.write(str(entry))
f.close()
f = atomic_ofstream(os.path.join(pkg.dbdir, "CONTENTS"))
write_contents(new_contents, root, f)
@@ -1272,7 +1253,7 @@ class vardbapi(dbapi):
self._bump_mtime(pkg.mycpv)
pkg._clear_contents_cache()
- class _owners_cache(object):
+ class _owners_cache:
"""
This class maintains an hash table that serves to index package
contents by mapping the basename of file to a list of possible
@@ -1336,9 +1317,9 @@ class vardbapi(dbapi):
counter = int(counter)
except ValueError:
counter = 0
- return (_unicode(cpv), counter, mtime)
+ return (str(cpv), counter, mtime)
- class _owners_db(object):
+ class _owners_db:
def __init__(self, vardb):
self._vardb = vardb
@@ -1465,7 +1446,7 @@ class vardbapi(dbapi):
len(hash_value) != 3:
continue
cpv, counter, mtime = hash_value
- if not isinstance(cpv, basestring):
+ if not isinstance(cpv, str):
continue
try:
current_hash = hash_pkg(cpv)
@@ -1552,7 +1533,7 @@ class vardbapi(dbapi):
for result in search_future.result():
yield result
-class vartree(object):
+class vartree:
"this tree will scan a var/db/pkg database located at root (passed to init)"
def __init__(self, root=None, virtual=DeprecationWarning, categories=None,
settings=None):
@@ -1609,8 +1590,7 @@ class vartree(object):
use_cache=use_cache))
if mymatch is None:
return ""
- else:
- return mymatch
+ return mymatch
def dep_match(self, mydep, use_cache=1):
"compatibility method -- we want to see all matches, not just visible ones"
@@ -1618,8 +1598,7 @@ class vartree(object):
mymatch = self.dbapi.match(mydep, use_cache=use_cache)
if mymatch is None:
return []
- else:
- return mymatch
+ return mymatch
def exists_specific(self, cpv):
return self.dbapi.cpv_exists(cpv)
@@ -1648,7 +1627,7 @@ class vartree(object):
def populate(self):
self.populated=1
-class dblink(object):
+class dblink:
"""
This class provides an interface to the installed package database
At present this is implemented as a text backend in /var/db/pkg.
@@ -3638,7 +3617,7 @@ class dblink(object):
symlink_collisions = []
destroot = self.settings['ROOT']
totfiles = len(file_list) + len(symlink_list)
- previous = monotonic()
+ previous = time.monotonic()
progress_shown = False
report_interval = 1.7 # seconds
falign = len("%d" % totfiles)
@@ -3647,7 +3626,7 @@ class dblink(object):
for i, (f, f_type) in enumerate(chain(
((f, "reg") for f in file_list),
((f, "sym") for f in symlink_list))):
- current = monotonic()
+ current = time.monotonic()
if current - previous > report_interval:
showMessage(_("%3d%% done, %*d files remaining ...\n") %
(i * 100 / totfiles, falign, totfiles - i))
@@ -3913,7 +3892,7 @@ class dblink(object):
for phase, messages in logentries.items():
for key, lines in messages:
funcname = funcnames[key]
- if isinstance(lines, basestring):
+ if isinstance(lines, str):
lines = [lines]
for line in lines:
for line in line.split('\n'):
@@ -4931,7 +4910,7 @@ class dblink(object):
self._installed_instance is not None
# this is supposed to merge a list of files. There will be 2 forms of argument passing.
- if isinstance(stufftomerge, basestring):
+ if isinstance(stufftomerge, str):
#A directory is specified. Figure out protection paths, listdir() it and process it.
mergelist = [join(stufftomerge, child) for child in \
os.listdir(join(srcroot, stufftomerge))]
@@ -4951,10 +4930,7 @@ class dblink(object):
mymd5 = None
myto = None
- if sys.hexversion >= 0x3030000:
- mymtime = mystat.st_mtime_ns
- else:
- mymtime = mystat[stat.ST_MTIME]
+ mymtime = mystat.st_mtime_ns
if stat.S_ISREG(mymode):
mymd5 = perform_md5(mysrc, calc_prelink=calc_prelink)
@@ -5097,10 +5073,7 @@ class dblink(object):
% (relative_path, myabsto)])
showMessage("%s %s -> %s\n" % (zing, mydest, myto))
- if sys.hexversion >= 0x3030000:
- outfile.write("sym "+myrealdest+" -> "+myto+" "+str(mymtime // 1000000000)+"\n")
- else:
- outfile.write("sym "+myrealdest+" -> "+myto+" "+str(mymtime)+"\n")
+ outfile.write("sym "+myrealdest+" -> "+myto+" "+str(mymtime // 1000000000)+"\n")
else:
showMessage(_("!!! Failed to move file.\n"),
level=logging.ERROR, noiselevel=-1)
@@ -5249,10 +5222,7 @@ class dblink(object):
pass
if mymtime != None:
- if sys.hexversion >= 0x3030000:
- outfile.write("obj "+myrealdest+" "+mymd5+" "+str(mymtime // 1000000000)+"\n")
- else:
- outfile.write("obj "+myrealdest+" "+mymd5+" "+str(mymtime)+"\n")
+ outfile.write("obj "+myrealdest+" "+mymd5+" "+str(mymtime // 1000000000)+"\n")
showMessage("%s %s\n" % (zing,mydest))
else:
# we are merging a fifo or device node
@@ -5470,7 +5440,7 @@ class dblink(object):
def setfile(self,fname,data):
kwargs = {}
- if fname == 'environment.bz2' or not isinstance(data, basestring):
+ if fname == 'environment.bz2' or not isinstance(data, str):
kwargs['mode'] = 'wb'
else:
kwargs['mode'] = 'w'
@@ -5527,7 +5497,7 @@ class dblink(object):
build_time = backup_dblink.getfile('BUILD_TIME')
try:
- build_time = long(build_time.strip())
+ build_time = int(build_time.strip())
except ValueError:
build_time = 0
diff --git a/lib/portage/dbapi/virtual.py b/lib/portage/dbapi/virtual.py
index 3f7e6c221..f62fc2a30 100644
--- a/lib/portage/dbapi/virtual.py
+++ b/lib/portage/dbapi/virtual.py
@@ -1,8 +1,6 @@
# Copyright 1998-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
from portage.dbapi import dbapi
from portage.dbapi.dep_expand import dep_expand
from portage.versions import cpv_getkey, _pkg_str
@@ -125,8 +123,7 @@ class fakedbapi(dbapi):
def cpv_all(self):
if self._multi_instance:
return [x[0] for x in self.cpvdict]
- else:
- return list(self.cpvdict)
+ return list(self.cpvdict)
def cpv_inject(self, mycpv, metadata=None):
"""Adds a cpv to the list of available packages. See the
@@ -215,7 +212,7 @@ class fakedbapi(dbapi):
raise KeyError(cpv)
metadata.update(values)
-class testdbapi(object):
+class testdbapi:
"""A dbapi instance with completely fake functions to get by hitting disk
TODO(antarus):
This class really needs to be rewritten to have better stubs; but these work for now.
diff --git a/lib/portage/debug.py b/lib/portage/debug.py
index 193e62291..4db9da53b 100644
--- a/lib/portage/debug.py
+++ b/lib/portage/debug.py
@@ -21,7 +21,7 @@ def set_trace(on=True):
sys.settrace(None)
threading.settrace(None)
-class trace_handler(object):
+class trace_handler:
def __init__(self):
python_system_paths = []
@@ -63,7 +63,7 @@ class trace_handler(object):
if len(my_repr) > self.max_repr_length:
my_repr = "'omitted'"
return "value=%s " % my_repr
- elif "exception" == event:
+ if "exception" == event:
my_repr = repr(arg[1])
if len(my_repr) > self.max_repr_length:
my_repr = "'omitted'"
@@ -100,7 +100,7 @@ class trace_handler(object):
my_locals[k] = "omitted"
return my_locals
-class prefix_trimmer(object):
+class prefix_trimmer:
def __init__(self, prefix):
self.prefix = prefix
self.cut_index = len(prefix)
@@ -112,9 +112,9 @@ class prefix_trimmer(object):
The previous result is automatically cached."""
if s == self.previous:
return self.previous_trimmed
+
+ if s.startswith(self.prefix):
+ self.previous_trimmed = s[self.cut_index:]
else:
- if s.startswith(self.prefix):
- self.previous_trimmed = s[self.cut_index:]
- else:
- self.previous_trimmed = s
- return self.previous_trimmed
+ self.previous_trimmed = s
+ return self.previous_trimmed
diff --git a/lib/portage/dep/__init__.py b/lib/portage/dep/__init__.py
index 72988357a..36f0dc8c9 100644
--- a/lib/portage/dep/__init__.py
+++ b/lib/portage/dep/__init__.py
@@ -2,8 +2,6 @@
# Copyright 2003-2018 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
__all__ = [
'Atom', 'best_match_to_list', 'cpvequal',
'dep_getcpv', 'dep_getkey', 'dep_getslot',
@@ -17,6 +15,7 @@ __all__ = [
import re, sys
import warnings
+from functools import lru_cache
import portage
portage.proxy.lazyimport.lazyimport(globals(),
@@ -31,12 +30,6 @@ from portage.versions import _cp, _cpv, _pkg_str, _slot, _unknown_repo, _vr, \
catpkgsplit, vercmp, ververify
import portage.cache.mappings
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
- _unicode = str
-else:
- _unicode = unicode
# \w is [a-zA-Z0-9_]
@@ -78,7 +71,7 @@ def _match_slot(atom, pkg):
if pkg.slot == atom.slot:
if not atom.sub_slot:
return True
- elif atom.sub_slot == pkg.sub_slot:
+ if atom.sub_slot == pkg.sub_slot:
return True
return False
@@ -353,7 +346,7 @@ class paren_normalize(list):
return dest
i = iter(src)
for x in i:
- if isinstance(x, basestring):
+ if isinstance(x, str):
if x in ('||', '^^'):
y = self._zap_parens(next(i), [], disjunction=True)
if len(y) == 1:
@@ -404,49 +397,10 @@ def paren_enclose(mylist, unevaluated_atom=False, opconvert=False):
mystrparts.append(x)
return " ".join(mystrparts)
-def use_reduce(depstr, uselist=(), masklist=(), matchall=False, excludeall=(), is_src_uri=False, \
- eapi=None, opconvert=False, flat=False, is_valid_flag=None, token_class=None, matchnone=False,
- subset=None):
- """
- Takes a dep string and reduces the use? conditionals out, leaving an array
- with subarrays. All redundant brackets are removed.
-
- @param depstr: depstring
- @type depstr: String
- @param uselist: Sequence of use enabled flags
- @type uselist: Sequence
- @param masklist: Sequence of masked flags (always treated as disabled)
- @type masklist: Sequence
- @param matchall: Treat all conditionals as active. Used by repoman.
- @type matchall: Bool
- @param excludeall: Sequence of flags for which negated conditionals are always treated as inactive.
- @type excludeall: Sequence
- @param is_src_uri: Indicates if depstr represents a SRC_URI
- @type is_src_uri: Bool
- @param eapi: Indicates the EAPI the dep string has to comply to
- @type eapi: String
- @param opconvert: Put every operator as first element into it's argument list
- @type opconvert: Bool
- @param flat: Create a flat list of all tokens
- @type flat: Bool
- @param is_valid_flag: Function that decides if a given use flag might be used in use conditionals
- @type is_valid_flag: Function
- @param token_class: Convert all non operator tokens into this class
- @type token_class: Class
- @param matchnone: Treat all conditionals as inactive. Used by digestgen().
- @type matchnone: Bool
- @param subset: Select a subset of dependencies conditional on the given flags
- @type subset: Sequence
- @rtype: List
- @return: The use reduced depend array
- """
- if isinstance(depstr, list):
- if portage._internal_caller:
- warnings.warn(_("Passing paren_reduced dep arrays to %s is deprecated. " + \
- "Pass the original dep string instead.") % \
- ('portage.dep.use_reduce',), DeprecationWarning, stacklevel=2)
- depstr = paren_enclose(depstr)
-
+@lru_cache(1024)
+def _use_reduce_cached(depstr, uselist, masklist, matchall, excludeall, \
+ is_src_uri, eapi, opconvert, flat, is_valid_flag, token_class, \
+ matchnone,subset):
if opconvert and flat:
raise ValueError("portage.dep.use_reduce: 'opconvert' and 'flat' are mutually exclusive")
@@ -597,13 +551,12 @@ def use_reduce(depstr, uselist=(), masklist=(), matchall=False, excludeall=(), i
stack[level].extend(l)
continue
- if stack[level] and isinstance(stack[level][-1],
- basestring):
+ if stack[level] and isinstance(stack[level][-1], str):
if stack[level][-1] == "||" and not l:
#Optimize: || ( ) -> .
if not eapi_attrs.empty_groups_always_true:
# in EAPI 7+, we need to fail here
- l.append((token_class or _unicode)("__const__/empty-any-of"))
+ l.append((token_class or str)("__const__/empty-any-of"))
stack[level].pop()
elif stack[level][-1][-1] == "?":
#The last token before the '(' that matches the current ')'
@@ -626,11 +579,10 @@ def use_reduce(depstr, uselist=(), masklist=(), matchall=False, excludeall=(), i
#ends in a non-operator. This is almost equivalent to stack[level][-1]=="||",
#expect that it skips empty levels.
while k>=0:
- if stack[k] and isinstance(stack[k][-1],
- basestring):
+ if stack[k] and isinstance(stack[k][-1], str):
if stack[k][-1] == "||":
return k
- elif stack[k][-1][-1] != "?":
+ if stack[k][-1][-1] != "?":
return -1
k -= 1
return -1
@@ -769,6 +721,65 @@ def use_reduce(depstr, uselist=(), masklist=(), matchall=False, excludeall=(), i
return stack[0]
+def use_reduce(depstr, uselist=(), masklist=(), matchall=False, excludeall=(), is_src_uri=False, \
+ eapi=None, opconvert=False, flat=False, is_valid_flag=None, token_class=None, matchnone=False,
+ subset=None):
+ """
+ Takes a dep string and reduces the use? conditionals out, leaving an array
+ with subarrays. All redundant brackets are removed.
+
+ @param depstr: depstring
+ @type depstr: String
+ @param uselist: Sequence of use enabled flags
+ @type uselist: Sequence
+ @param masklist: Sequence of masked flags (always treated as disabled)
+ @type masklist: Sequence
+ @param matchall: Treat all conditionals as active. Used by repoman.
+ @type matchall: Bool
+ @param excludeall: Sequence of flags for which negated conditionals are always treated as inactive.
+ @type excludeall: Sequence
+ @param is_src_uri: Indicates if depstr represents a SRC_URI
+ @type is_src_uri: Bool
+ @param eapi: Indicates the EAPI the dep string has to comply to
+ @type eapi: String
+ @param opconvert: Put every operator as first element into it's argument list
+ @type opconvert: Bool
+ @param flat: Create a flat list of all tokens
+ @type flat: Bool
+ @param is_valid_flag: Function that decides if a given use flag might be used in use conditionals
+ @type is_valid_flag: Function
+ @param token_class: Convert all non operator tokens into this class
+ @type token_class: Class
+ @param matchnone: Treat all conditionals as inactive. Used by digestgen().
+ @type matchnone: Bool
+ @param subset: Select a subset of dependencies conditional on the given flags
+ @type subset: Sequence
+ @rtype: List
+ @return: The use reduced depend array
+ """
+ if isinstance(depstr, list):
+ if portage._internal_caller:
+ warnings.warn(_("Passing paren_reduced dep arrays to %s is deprecated. " + \
+ "Pass the original dep string instead.") % \
+ ('portage.dep.use_reduce',), DeprecationWarning, stacklevel=2)
+ depstr = paren_enclose(depstr)
+
+ if uselist is not None:
+ uselist = frozenset(uselist)
+ if masklist is not None:
+ masklist = frozenset(masklist)
+ if excludeall is not None:
+ excludeall = frozenset(excludeall)
+ if subset is not None:
+ subset = frozenset(subset)
+
+ result = _use_reduce_cached(depstr, uselist, masklist, matchall, \
+ excludeall, is_src_uri, eapi, opconvert, flat, is_valid_flag, \
+ token_class, matchnone, subset)
+
+ # The list returned by this function may be modified, so return a copy.
+ return result[:]
+
def dep_opconvert(deplist):
"""
Iterate recursively through a list of deps, if the
@@ -829,12 +840,12 @@ def flatten(mylist):
newlist.append(x)
return newlist
-class _use_dep(object):
+class _use_dep:
__slots__ = ("_eapi_attrs", "conditional", "missing_enabled", "missing_disabled",
"disabled", "enabled", "tokens", "required")
- class _conditionals_class(object):
+ class _conditionals_class:
__slots__ = ("enabled", "disabled", "equal", "not_equal")
def items(self):
@@ -949,22 +960,11 @@ class _use_dep(object):
def __bool__(self):
return bool(self.tokens)
- if sys.hexversion < 0x3000000:
- __nonzero__ = __bool__
-
def __str__(self):
if not self.tokens:
return ""
return "[%s]" % (",".join(self.tokens),)
- if sys.hexversion < 0x3000000:
-
- __unicode__ = __str__
-
- def __str__(self):
- return _unicode_encode(self.__unicode__(),
- encoding=_encodings['content'], errors='backslashreplace')
-
def __repr__(self):
return "portage.dep._use_dep(%s)" % repr(self.tokens)
@@ -1209,7 +1209,7 @@ class _use_dep(object):
return _use_dep(tokens, self._eapi_attrs, enabled_flags=enabled_flags, disabled_flags=disabled_flags,
missing_enabled=missing_enabled, missing_disabled=missing_disabled, required=self.required)
-class Atom(_unicode):
+class Atom(str):
"""
For compatibility with existing atom string manipulation code, this
@@ -1222,10 +1222,10 @@ class Atom(_unicode):
# Distiguishes soname atoms from other atom types
soname = False
- class _blocker(object):
+ class _blocker:
__slots__ = ("overlap",)
- class _overlap(object):
+ class _overlap:
__slots__ = ("forbid",)
def __init__(self, forbid=False):
@@ -1236,7 +1236,7 @@ class Atom(_unicode):
def __new__(cls, s, unevaluated_atom=None, allow_wildcard=False, allow_repo=None,
_use=None, eapi=None, is_valid_flag=None, allow_build_id=None):
- return _unicode.__new__(cls, s)
+ return str.__new__(cls, s)
def __init__(self, s, unevaluated_atom=None, allow_wildcard=False, allow_repo=None,
_use=None, eapi=None, is_valid_flag=None, allow_build_id=None):
@@ -1244,13 +1244,13 @@ class Atom(_unicode):
# This is an efficiency assertion, to ensure that the Atom
# constructor is not called redundantly.
raise TypeError(_("Expected %s, got %s") % \
- (_unicode, type(s)))
+ (str, type(s)))
- if not isinstance(s, _unicode):
- # Avoid TypeError from _unicode.__init__ with PyPy.
+ if not isinstance(s, str):
+ # Avoid TypeError from str.__init__ with PyPy.
s = _unicode_decode(s)
- _unicode.__init__(s)
+ str.__init__(s)
eapi_attrs = _get_eapi_attrs(eapi)
atom_re = _get_atom_re(eapi_attrs)
@@ -1417,7 +1417,7 @@ class Atom(_unicode):
unevaluated_atom.use is not None:
# unevaluated_atom.use is used for IUSE checks when matching
# packages, so it must not propagate to without_use
- without_use = Atom(_unicode(self),
+ without_use = Atom(str(self),
allow_wildcard=allow_wildcard,
allow_repo=allow_repo,
eapi=eapi)
@@ -1433,9 +1433,9 @@ class Atom(_unicode):
self.__dict__['unevaluated_atom'] = self
if eapi is not None:
- if not isinstance(eapi, basestring):
+ if not isinstance(eapi, str):
raise TypeError('expected eapi argument of ' + \
- '%s, got %s: %s' % (basestring, type(eapi), eapi,))
+ '%s, got %s: %s' % (str, type(eapi), eapi,))
if self.slot and not eapi_attrs.slot_deps:
raise InvalidAtom(
_("Slot deps are not allowed in EAPI %s: '%s'") \
@@ -1497,7 +1497,7 @@ class Atom(_unicode):
if self.repo is not None:
atom += _repo_separator + self.repo
if self.use is not None:
- atom += _unicode(self.use)
+ atom += str(self.use)
return Atom(atom,
allow_repo=True, allow_wildcard=True)
@@ -1513,7 +1513,7 @@ class Atom(_unicode):
atom += self.slot_operator
atom += _repo_separator + repo
if self.use is not None:
- atom += _unicode(self.use)
+ atom += str(self.use)
return Atom(atom, allow_repo=True, allow_wildcard=True)
def with_slot(self, slot):
@@ -1521,7 +1521,7 @@ class Atom(_unicode):
if self.repo is not None:
atom += _repo_separator + self.repo
if self.use is not None:
- atom += _unicode(self.use)
+ atom += str(self.use)
return Atom(atom, allow_repo=True, allow_wildcard=True)
def __setattr__(self, name, value):
@@ -1579,7 +1579,7 @@ class Atom(_unicode):
if self.slot_operator is not None:
atom += self.slot_operator
use_dep = self.use.evaluate_conditionals(use)
- atom += _unicode(use_dep)
+ atom += str(use_dep)
return Atom(atom, unevaluated_atom=self, allow_repo=(self.repo is not None), _use=use_dep)
def violated_conditionals(self, other_use, is_valid_flag, parent_use=None):
@@ -1607,7 +1607,7 @@ class Atom(_unicode):
if self.slot_operator is not None:
atom += self.slot_operator
use_dep = self.use.violated_conditionals(other_use, is_valid_flag, parent_use)
- atom += _unicode(use_dep)
+ atom += str(use_dep)
return Atom(atom, unevaluated_atom=self, allow_repo=(self.repo is not None), _use=use_dep)
def _eval_qa_conditionals(self, use_mask, use_force):
@@ -1623,7 +1623,7 @@ class Atom(_unicode):
if self.slot_operator is not None:
atom += self.slot_operator
use_dep = self.use._eval_qa_conditionals(use_mask, use_force)
- atom += _unicode(use_dep)
+ atom += str(use_dep)
return Atom(atom, unevaluated_atom=self, allow_repo=(self.repo is not None), _use=use_dep)
def __copy__(self):
@@ -1701,12 +1701,10 @@ class ExtendedAtomDict(portage.cache.mappings.MutableMapping):
def __delitem__(self, cp):
if "*" in cp:
return self._extended.__delitem__(cp)
- else:
- return self._normal.__delitem__(cp)
+ return self._normal.__delitem__(cp)
- if sys.hexversion >= 0x3000000:
- keys = __iter__
- items = iteritems
+ keys = __iter__
+ items = iteritems
def __len__(self):
return len(self._normal) + len(self._extended)
@@ -1714,12 +1712,11 @@ class ExtendedAtomDict(portage.cache.mappings.MutableMapping):
def setdefault(self, cp, default=None):
if "*" in cp:
return self._extended.setdefault(cp, default)
- else:
- return self._normal.setdefault(cp, default)
+ return self._normal.setdefault(cp, default)
def __getitem__(self, cp):
- if not isinstance(cp, basestring):
+ if not isinstance(cp, str):
raise KeyError(cp)
if '*' in cp:
@@ -1832,8 +1829,7 @@ def dep_getslot(mydep):
bracket = mydep.find("[", colon)
if bracket == -1:
return mydep[colon+1:]
- else:
- return mydep[colon+1:bracket]
+ return mydep[colon+1:bracket]
return None
def dep_getrepo(mydep):
@@ -1864,8 +1860,7 @@ def dep_getrepo(mydep):
bracket = mydep.find("[", colon)
if bracket == -1:
return mydep[colon+2:]
- else:
- return mydep[colon+2:bracket]
+ return mydep[colon+2:bracket]
return None
def remove_slot(mydep):
@@ -1961,7 +1956,7 @@ def isvalidatom(atom, allow_blockers=False, allow_wildcard=False,
if eapi is not None and isinstance(atom, Atom) and atom.eapi != eapi:
# We'll construct a new atom with the given eapi.
- atom = _unicode(atom)
+ atom = str(atom)
try:
if not isinstance(atom, Atom):
@@ -2509,7 +2504,7 @@ def get_required_use_flags(required_use, eapi=None):
return frozenset(used_flags)
-class _RequiredUseLeaf(object):
+class _RequiredUseLeaf:
__slots__ = ('_satisfied', '_token')
@@ -2520,7 +2515,7 @@ class _RequiredUseLeaf(object):
def tounicode(self):
return self._token
-class _RequiredUseBranch(object):
+class _RequiredUseBranch:
__slots__ = ('_children', '_operator', '_parent', '_satisfied')
@@ -2564,8 +2559,6 @@ class _RequiredUseBranch(object):
return " ".join(tokens)
- if sys.hexversion < 0x3000000:
- __nonzero__ = __bool__
def check_required_use(required_use, use, iuse_match, eapi=None):
"""
@@ -2618,11 +2611,11 @@ def check_required_use(required_use, use, iuse_match, eapi=None):
if operator == "||":
return (True in argument)
- elif operator == "^^":
+ if operator == "^^":
return (argument.count(True) == 1)
- elif operator == "??":
+ if operator == "??":
return (argument.count(True) <= 1)
- elif operator[-1] == "?":
+ if operator[-1] == "?":
return (False not in argument)
mysplit = required_use.split()
diff --git a/lib/portage/dep/_dnf.py b/lib/portage/dep/_dnf.py
index 59657fd6a..1b14d2b43 100644
--- a/lib/portage/dep/_dnf.py
+++ b/lib/portage/dep/_dnf.py
@@ -1,8 +1,6 @@
# Copyright 2017 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import itertools
@@ -85,6 +83,6 @@ def contains_disjunction(dep_struct):
assert x, 'Normalization error, empty conjunction found in %s' % (dep_struct,)
if x[0] == '||':
return True
- elif is_disjunction and contains_disjunction(x):
+ if is_disjunction and contains_disjunction(x):
return True
return False
diff --git a/lib/portage/dep/_slot_operator.py b/lib/portage/dep/_slot_operator.py
index a9f74382c..29bf8e1b1 100644
--- a/lib/portage/dep/_slot_operator.py
+++ b/lib/portage/dep/_slot_operator.py
@@ -1,8 +1,6 @@
# Copyright 2012-2018 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
from portage.dep import Atom, paren_enclose, use_reduce
from portage.eapi import _get_eapi_attrs
from portage.exception import InvalidData
diff --git a/lib/portage/dep/dep_check.py b/lib/portage/dep/dep_check.py
index 9534590bf..625599725 100644
--- a/lib/portage/dep/dep_check.py
+++ b/lib/portage/dep/dep_check.py
@@ -1,8 +1,6 @@
# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
__all__ = ['dep_check', 'dep_eval', 'dep_wordreduce', 'dep_zapdeps']
import collections
@@ -285,14 +283,13 @@ def dep_eval(deplist):
if len(deplist) == 1:
return 1
return 0
- else:
- for x in deplist:
- if isinstance(x, list):
- if dep_eval(x)==0:
- return 0
- elif x==0 or x==2:
+ for x in deplist:
+ if isinstance(x, list):
+ if dep_eval(x)==0:
return 0
- return 1
+ elif x==0 or x==2:
+ return 0
+ return 1
class _dep_choice(SlotObject):
__slots__ = ('atoms', 'slot_map', 'cp_map', 'all_available',
diff --git a/lib/portage/dep/soname/SonameAtom.py b/lib/portage/dep/soname/SonameAtom.py
index 5743544aa..62b2ee5e1 100644
--- a/lib/portage/dep/soname/SonameAtom.py
+++ b/lib/portage/dep/soname/SonameAtom.py
@@ -1,13 +1,10 @@
# Copyright 2015-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
-import sys
from portage import _encodings, _unicode_encode
-class SonameAtom(object):
+class SonameAtom:
__slots__ = ("multilib_category", "soname", "_hash_key",
"_hash_value")
@@ -58,14 +55,6 @@ class SonameAtom(object):
def __str__(self):
return "%s: %s" % (self.multilib_category, self.soname)
- if sys.hexversion < 0x3000000:
-
- __unicode__ = __str__
-
- def __str__(self):
- return _unicode_encode(self.__unicode__(),
- encoding=_encodings['content'])
-
def match(self, pkg):
"""
Check if the given package instance matches this atom. Unbuilt
diff --git a/lib/portage/dep/soname/multilib_category.py b/lib/portage/dep/soname/multilib_category.py
index 37af98705..301c62a35 100644
--- a/lib/portage/dep/soname/multilib_category.py
+++ b/lib/portage/dep/soname/multilib_category.py
@@ -32,8 +32,6 @@
# for given installation, we are only interested in tracking multilib
# ABIs for a single OS.
-from __future__ import unicode_literals
-
from portage.util.elf.constants import (
EF_MIPS_ABI,
EF_MIPS_ABI2,
diff --git a/lib/portage/dep/soname/parse.py b/lib/portage/dep/soname/parse.py
index 3f3757209..d83ff12d9 100644
--- a/lib/portage/dep/soname/parse.py
+++ b/lib/portage/dep/soname/parse.py
@@ -1,8 +1,6 @@
# Copyright 2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
from portage.exception import InvalidData
from portage.localization import _
from portage.dep.soname.SonameAtom import SonameAtom
diff --git a/lib/portage/dispatch_conf.py b/lib/portage/dispatch_conf.py
index 2fab19f1a..71693bb36 100644
--- a/lib/portage/dispatch_conf.py
+++ b/lib/portage/dispatch_conf.py
@@ -6,7 +6,7 @@
# Library by Wayne Davison <gentoo@blorf.net>, derived from code
# written by Jeremy Wohl (http://igmus.org)
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
import errno
import io
@@ -97,7 +97,7 @@ def diff_mixed(func, file1, file2):
if tempdir is not None:
shutil.rmtree(tempdir)
-class diff_mixed_wrapper(object):
+class diff_mixed_wrapper:
def __init__(self, f, *args):
self._func = f
diff --git a/lib/portage/eclass_cache.py b/lib/portage/eclass_cache.py
index d2d9e2710..5a8e6ee6a 100644
--- a/lib/portage/eclass_cache.py
+++ b/lib/portage/eclass_cache.py
@@ -1,13 +1,10 @@
-# Copyright 2005-2014 Gentoo Foundation
+# Copyright 2005-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# Author(s): Nicholas Carpaski (carpaski@gentoo.org), Brian Harring (ferringb@gentoo.org)
-from __future__ import unicode_literals
-
__all__ = ["cache"]
import stat
-import sys
import operator
import warnings
from portage.util import normalize_path
@@ -17,12 +14,8 @@ from portage import os
from portage import checksum
from portage import _shell_quote
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- long = int
-
-class hashed_path(object):
+class hashed_path:
def __init__(self, location):
self.location = location
@@ -30,11 +23,11 @@ class hashed_path(object):
def __getattr__(self, attr):
if attr == 'mtime':
# use stat.ST_MTIME; accessing .st_mtime gets you a float
- # depending on the python version, and long(float) introduces
+ # depending on the python version, and int(float) introduces
# some rounding issues that aren't present for people using
# the straight c api.
# thus use the defacto python compatibility work around;
- # access via index, which guarantees you get the raw long.
+ # access via index, which guarantees you get the raw int.
try:
self.mtime = obj = os.stat(self.location)[stat.ST_MTIME]
except OSError as e:
@@ -57,7 +50,7 @@ class hashed_path(object):
def __repr__(self):
return "<portage.eclass_cache.hashed_path('%s')>" % (self.location,)
-class cache(object):
+class cache:
"""
Maintains the cache information about eclasses used in ebuild.
"""
diff --git a/lib/portage/elog/__init__.py b/lib/portage/elog/__init__.py
index cc086123f..ad6048481 100644
--- a/lib/portage/elog/__init__.py
+++ b/lib/portage/elog/__init__.py
@@ -3,9 +3,6 @@
# Distributed under the terms of the GNU General Public License v2
import sys
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
import portage
portage.proxy.lazyimport.lazyimport(globals(),
@@ -58,7 +55,7 @@ def _combine_logentries(logentries):
if previous_type != msgtype:
previous_type = msgtype
rValue.append("%s: %s" % (msgtype, phase))
- if isinstance(msgcontent, basestring):
+ if isinstance(msgcontent, str):
rValue.append(msgcontent.rstrip("\n"))
else:
for line in msgcontent:
@@ -188,4 +185,3 @@ def elog_process(cpv, mysettings, phasefilter=None):
noiselevel=-1)
except PortageException as e:
writemsg("%s\n" % str(e), noiselevel=-1)
-
diff --git a/lib/portage/elog/messages.py b/lib/portage/elog/messages.py
index a4897d8d8..3731e6c4d 100644
--- a/lib/portage/elog/messages.py
+++ b/lib/portage/elog/messages.py
@@ -122,8 +122,7 @@ def _elog_base(level, msg, phase="other", key=None, color=None, out=None):
if out in (sys.stdout, sys.stderr):
formatted_msg = _unicode_encode(formatted_msg,
encoding=_encodings['stdio'], errors='backslashreplace')
- if sys.hexversion >= 0x3000000:
- out = out.buffer
+ out = out.buffer
out.write(formatted_msg)
@@ -173,7 +172,7 @@ _functions = { "einfo": ("INFO", "GOOD"),
"eerror": ("ERROR", "BAD"),
}
-class _make_msgfunction(object):
+class _make_msgfunction:
__slots__ = ('_color', '_level')
def __init__(self, level, color):
self._level = level
diff --git a/lib/portage/elog/mod_echo.py b/lib/portage/elog/mod_echo.py
index 8cdf6ac7d..52e8fad8d 100644
--- a/lib/portage/elog/mod_echo.py
+++ b/lib/portage/elog/mod_echo.py
@@ -9,9 +9,6 @@ from portage.output import EOutput, colorize
from portage.const import EBUILD_PHASES
from portage.localization import _
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
_items = []
def process(mysettings, key, logentries, fulltext):
@@ -61,7 +58,7 @@ def _finalize():
"ERROR": printer.eerror,
"LOG": printer.einfo,
"QA": printer.ewarn}
- if isinstance(msgcontent, basestring):
+ if isinstance(msgcontent, str):
msgcontent = [msgcontent]
for line in msgcontent:
fmap[msgtype](line.strip("\n"))
diff --git a/lib/portage/elog/mod_mail_summary.py b/lib/portage/elog/mod_mail_summary.py
index 0bd67f22b..31c9d25b0 100644
--- a/lib/portage/elog/mod_mail_summary.py
+++ b/lib/portage/elog/mod_mail_summary.py
@@ -50,7 +50,7 @@ def finalize():
def _finalize(mysettings, items):
if len(items) == 0:
return
- elif len(items) == 1:
+ if len(items) == 1:
count = _("one package")
else:
count = _("multiple packages")
@@ -68,7 +68,7 @@ def _finalize(mysettings, items):
mybody = _("elog messages for the following packages generated by "
"process %(pid)d on host %(host)s:\n") % {"pid": os.getpid(), "host": socket.getfqdn()}
for key in items:
- mybody += "- %s\n" % key
+ mybody += "- %s\n" % key
mymessage = portage.mail.create_message(myfrom, myrecipient, mysubject,
mybody, attachments=list(items.values()))
diff --git a/lib/portage/elog/mod_save_summary.py b/lib/portage/elog/mod_save_summary.py
index e4924b66b..946a1ad4c 100644
--- a/lib/portage/elog/mod_save_summary.py
+++ b/lib/portage/elog/mod_save_summary.py
@@ -2,11 +2,8 @@
# Copyright 2006-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import errno
import io
-import sys
import time
import portage
from portage import os
@@ -75,8 +72,6 @@ def process(mysettings, key, logentries, fulltext):
mode=elogdir_grp_mode, mask=0)
time_fmt = "%Y-%m-%d %H:%M:%S %Z"
- if sys.hexversion < 0x3000000:
- time_fmt = _unicode_encode(time_fmt)
time_str = time.strftime(time_fmt, time.localtime(time.time()))
# Avoid potential UnicodeDecodeError in Python 2, since strftime
# returns bytes in Python 2, and %Z may contain non-ascii chars.
diff --git a/lib/portage/elog/mod_syslog.py b/lib/portage/elog/mod_syslog.py
index 8b26ffa1e..4dabacc52 100644
--- a/lib/portage/elog/mod_syslog.py
+++ b/lib/portage/elog/mod_syslog.py
@@ -2,14 +2,10 @@
# Copyright 2006-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-import sys
import syslog
from portage.const import EBUILD_PHASES
from portage import _encodings
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
_pri = {
"INFO" : syslog.LOG_INFO,
@@ -25,13 +21,9 @@ def process(mysettings, key, logentries, fulltext):
if not phase in logentries:
continue
for msgtype, msgcontent in logentries[phase]:
- if isinstance(msgcontent, basestring):
+ if isinstance(msgcontent, str):
msgcontent = [msgcontent]
for line in msgcontent:
line = "%s: %s: %s" % (key, phase, line)
- if sys.hexversion < 0x3000000 and not isinstance(line, bytes):
- # Avoid TypeError from syslog.syslog()
- line = line.encode(_encodings['content'],
- 'backslashreplace')
syslog.syslog(_pri[msgtype], line.rstrip("\n"))
syslog.closelog()
diff --git a/lib/portage/emaint/main.py b/lib/portage/emaint/main.py
index f448d6baa..c743f9bc7 100644
--- a/lib/portage/emaint/main.py
+++ b/lib/portage/emaint/main.py
@@ -13,7 +13,7 @@ from portage.module import Modules
from portage.progress import ProgressBar
from portage.emaint.defaults import DEFAULT_OPTIONS
-class OptionItem(object):
+class OptionItem:
"""class to hold module ArgumentParser options data
"""
@@ -100,7 +100,7 @@ def module_opts(module_controller, module):
return _usage
-class TaskHandler(object):
+class TaskHandler:
"""Handles the running of the tasks it is given"""
def __init__(self, show_progress_bar=True, verbose=True, callback=None, module_output=None):
diff --git a/lib/portage/emaint/modules/binhost/binhost.py b/lib/portage/emaint/modules/binhost/binhost.py
index cf9516112..1cdb3634b 100644
--- a/lib/portage/emaint/modules/binhost/binhost.py
+++ b/lib/portage/emaint/modules/binhost/binhost.py
@@ -1,4 +1,4 @@
-# Copyright 2005-2014 Gentoo Foundation
+# Copyright 2005-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import errno
@@ -9,13 +9,9 @@ from portage import os
from portage.util import writemsg
from portage.versions import _pkg_str
-import sys
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- long = int
-class BinhostHandler(object):
+class BinhostHandler:
short_desc = "Generate a metadata index for binary packages"
@@ -54,9 +50,9 @@ class BinhostHandler(object):
return False
try:
- if long(mtime) != s[stat.ST_MTIME]:
+ if int(mtime) != s[stat.ST_MTIME]:
return True
- if long(size) != long(s.st_size):
+ if int(size) != int(s.st_size):
return True
except ValueError:
return True
diff --git a/lib/portage/emaint/modules/config/config.py b/lib/portage/emaint/modules/config/config.py
index a0d56992c..26edca649 100644
--- a/lib/portage/emaint/modules/config/config.py
+++ b/lib/portage/emaint/modules/config/config.py
@@ -6,7 +6,7 @@ from portage import os
from portage.const import PRIVATE_PATH
from portage.util import grabdict, writedict
-class CleanConfig(object):
+class CleanConfig:
short_desc = "Discard any no longer installed configs from emerge's tracker list"
diff --git a/lib/portage/emaint/modules/logs/logs.py b/lib/portage/emaint/modules/logs/logs.py
index a3fa2b5b8..b197db718 100644
--- a/lib/portage/emaint/modules/logs/logs.py
+++ b/lib/portage/emaint/modules/logs/logs.py
@@ -14,7 +14,7 @@ ERROR_MESSAGES = {
}
-class CleanLogs(object):
+class CleanLogs:
short_desc = "Clean PORTAGE_LOGDIR logs"
diff --git a/lib/portage/emaint/modules/merges/merges.py b/lib/portage/emaint/modules/merges/merges.py
index e166150f4..a2b70edb8 100644
--- a/lib/portage/emaint/modules/merges/merges.py
+++ b/lib/portage/emaint/modules/merges/merges.py
@@ -11,7 +11,7 @@ import subprocess
import sys
import time
-class TrackingFile(object):
+class TrackingFile:
"""File for keeping track of failed merges."""
@@ -80,7 +80,7 @@ class TrackingFile(object):
return self.load().items().__iter__()
-class MergesHandler(object):
+class MergesHandler:
"""Handle failed package merges."""
short_desc = "Remove failed merges"
@@ -224,9 +224,9 @@ class MergesHandler(object):
if output:
results.append(output)
if proc.returncode != os.EX_OK:
- emerge_status = "Failed to emerge '%s'" % (' '.join(pkg_atoms))
+ emerge_status = "Failed to emerge '%s'" % (' '.join(pkg_atoms))
else:
- emerge_status = "Successfully emerged '%s'" % (' '.join(pkg_atoms))
+ emerge_status = "Successfully emerged '%s'" % (' '.join(pkg_atoms))
results.append(emerge_status)
return results
diff --git a/lib/portage/emaint/modules/move/move.py b/lib/portage/emaint/modules/move/move.py
index e9a6acb6b..e2df53fd8 100644
--- a/lib/portage/emaint/modules/move/move.py
+++ b/lib/portage/emaint/modules/move/move.py
@@ -7,7 +7,7 @@ from portage.exception import InvalidData
from _emerge.Package import Package
from portage.versions import _pkg_str
-class MoveHandler(object):
+class MoveHandler:
def __init__(self, tree, porttree):
self._tree = tree
diff --git a/lib/portage/emaint/modules/resume/resume.py b/lib/portage/emaint/modules/resume/resume.py
index 580643b26..759af74e9 100644
--- a/lib/portage/emaint/modules/resume/resume.py
+++ b/lib/portage/emaint/modules/resume/resume.py
@@ -4,7 +4,7 @@
import portage
-class CleanResume(object):
+class CleanResume:
short_desc = "Discard emerge --resume merge lists"
diff --git a/lib/portage/emaint/modules/sync/sync.py b/lib/portage/emaint/modules/sync/sync.py
index ac37fdcfa..a8da68065 100644
--- a/lib/portage/emaint/modules/sync/sync.py
+++ b/lib/portage/emaint/modules/sync/sync.py
@@ -1,9 +1,7 @@
-# Copyright 2014-2019 Gentoo Authors
+# Copyright 2014-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-import logging
import os
-import sys
import portage
portage._internal_caller = True
@@ -32,13 +30,8 @@ portage.proxy.lazyimport.lazyimport(globals(),
warn = create_color_func("WARN")
-if sys.hexversion >= 0x3000000:
- _basestring = str
-else:
- _basestring = basestring
-
-class SyncRepos(object):
+class SyncRepos:
short_desc = "Check repos.conf settings and/or sync repositories"
@@ -125,7 +118,7 @@ class SyncRepos(object):
return_messages = options.get('return-messages', False)
else:
return_messages = False
- if isinstance(repo_names, _basestring):
+ if isinstance(repo_names, str):
repo_names = repo_names.split()
success, repos, msgs = self._get_repos(auto_sync_only=False,
match_repos=repo_names)
diff --git a/lib/portage/emaint/modules/world/world.py b/lib/portage/emaint/modules/world/world.py
index d142c3dda..33fbaf58f 100644
--- a/lib/portage/emaint/modules/world/world.py
+++ b/lib/portage/emaint/modules/world/world.py
@@ -5,7 +5,7 @@ import portage
from portage import os
-class WorldHandler(object):
+class WorldHandler:
short_desc = "Fix problems in the world file"
@@ -90,4 +90,3 @@ class WorldHandler(object):
return (True, None)
finally:
world_set.unlock()
-
diff --git a/lib/portage/env/__init__.py b/lib/portage/env/__init__.py
index 17b66d17c..1c0d15fbd 100644
--- a/lib/portage/env/__init__.py
+++ b/lib/portage/env/__init__.py
@@ -1,3 +1,2 @@
# Copyright: 2007 Gentoo Foundation
# License: GPL2
-
diff --git a/lib/portage/env/loaders.py b/lib/portage/env/loaders.py
index f86988471..5fa5452af 100644
--- a/lib/portage/env/loaders.py
+++ b/lib/portage/env/loaders.py
@@ -69,7 +69,7 @@ def RecursiveFileLoader(filename):
yield filename
-class DataLoader(object):
+class DataLoader:
def __init__(self, validator):
f = validator
diff --git a/lib/portage/exception.py b/lib/portage/exception.py
index a1c3c5f17..30ab0c689 100644
--- a/lib/portage/exception.py
+++ b/lib/portage/exception.py
@@ -1,46 +1,21 @@
-# Copyright 1998-2019 Gentoo Authors
+# Copyright 1998-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import signal
-import sys
from portage import _encodings, _unicode_encode, _unicode_decode
from portage.localization import _
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
class PortageException(Exception):
"""General superclass for portage exceptions"""
- if sys.hexversion >= 0x3000000:
- def __init__(self, value):
- self.value = value[:]
-
- def __str__(self):
- if isinstance(self.value, str):
- return self.value
- else:
- return repr(self.value)
- else:
- def __init__(self, value):
- self.value = value[:]
- if isinstance(self.value, basestring):
- self.value = _unicode_decode(self.value,
- encoding=_encodings['content'], errors='replace')
-
- def __unicode__(self):
- if isinstance(self.value, unicode):
- return self.value
- else:
- return _unicode_decode(repr(self.value),
- encoding=_encodings['content'], errors='replace')
-
- def __str__(self):
- if isinstance(self.value, unicode):
- return _unicode_encode(self.value,
- encoding=_encodings['content'], errors='backslashreplace')
- else:
- return repr(self.value)
+ def __init__(self, value):
+ self.value = value[:]
+
+ def __str__(self):
+ if isinstance(self.value, str):
+ return self.value
+ return repr(self.value)
+
class PortageKeyError(KeyError, PortageException):
__doc__ = KeyError.__doc__
@@ -180,7 +155,7 @@ class UnsupportedAPIException(PortagePackageException):
self.cpv, self.eapi = cpv, eapi
def __str__(self):
eapi = self.eapi
- if not isinstance(eapi, basestring):
+ if not isinstance(eapi, str):
eapi = str(eapi)
eapi = eapi.lstrip("-")
msg = _("Unable to do any operations on '%(cpv)s', since "
@@ -190,13 +165,6 @@ class UnsupportedAPIException(PortagePackageException):
return _unicode_decode(msg,
encoding=_encodings['content'], errors='replace')
- if sys.hexversion < 0x3000000:
-
- __unicode__ = __str__
-
- def __str__(self):
- return _unicode_encode(self.__unicode__(),
- encoding=_encodings['content'], errors='backslashreplace')
class SignatureException(PortageException):
"""Signature was not present in the checked file"""
@@ -212,4 +180,3 @@ class InvalidSignature(SignatureException):
class UntrustedSignature(SignatureException):
"""Signature was not certified to the desired security level"""
-
diff --git a/lib/portage/getbinpkg.py b/lib/portage/getbinpkg.py
index 997cd2eab..0bcf45b49 100644
--- a/lib/portage/getbinpkg.py
+++ b/lib/portage/getbinpkg.py
@@ -2,8 +2,6 @@
# Copyright 2003-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
from portage.output import colorize
from portage.cache.mappings import slot_dict_class
from portage.localization import _
@@ -15,6 +13,7 @@ from portage import _unicode_encode
from portage.package.ebuild.fetch import _hide_url_passwd
from _emerge.Package import _all_metadata_keys
+import pickle
import sys
import socket
import time
@@ -25,20 +24,8 @@ import warnings
_all_errors = [NotImplementedError, ValueError, socket.error]
-try:
- from html.parser import HTMLParser as html_parser_HTMLParser
-except ImportError:
- from HTMLParser import HTMLParser as html_parser_HTMLParser
-
-try:
- from urllib.parse import unquote as urllib_parse_unquote
-except ImportError:
- from urllib2 import unquote as urllib_parse_unquote
-
-try:
- import cPickle as pickle
-except ImportError:
- import pickle
+from html.parser import HTMLParser as html_parser_HTMLParser
+from urllib.parse import unquote as urllib_parse_unquote
try:
import ftplib
@@ -48,16 +35,10 @@ else:
_all_errors.extend(ftplib.all_errors)
try:
- try:
- from http.client import HTTPConnection as http_client_HTTPConnection
- from http.client import BadStatusLine as http_client_BadStatusLine
- from http.client import ResponseNotReady as http_client_ResponseNotReady
- from http.client import error as http_client_error
- except ImportError:
- from httplib import HTTPConnection as http_client_HTTPConnection
- from httplib import BadStatusLine as http_client_BadStatusLine
- from httplib import ResponseNotReady as http_client_ResponseNotReady
- from httplib import error as http_client_error
+ from http.client import HTTPConnection as http_client_HTTPConnection
+ from http.client import BadStatusLine as http_client_BadStatusLine
+ from http.client import ResponseNotReady as http_client_ResponseNotReady
+ from http.client import error as http_client_error
except ImportError as e:
sys.stderr.write(colorize("BAD", "!!! CANNOT IMPORT HTTP.CLIENT: ") + str(e) + "\n")
else:
@@ -65,9 +46,6 @@ else:
_all_errors = tuple(_all_errors)
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- long = int
def make_metadata_dict(data):
@@ -194,10 +172,7 @@ def create_conn(baseurl, conn=None):
# http.client ImportError handler (like during stage1 -> stage2
# builds where USE=ssl is disabled for python).
try:
- try:
- from http.client import HTTPSConnection as http_client_HTTPSConnection
- except ImportError:
- from httplib import HTTPSConnection as http_client_HTTPSConnection
+ from http.client import HTTPSConnection as http_client_HTTPSConnection
except ImportError:
raise NotImplementedError(
_("python must have ssl enabled for https support"))
@@ -460,8 +435,7 @@ def file_get_metadata(baseurl, conn=None, chunk_size=3000):
if not keepconnection:
conn.close()
return myid
- else:
- xpak_data = data[len(data) - (xpaksize + 8):-8]
+ xpak_data = data[len(data) - (xpaksize + 8):-8]
del data
myid = portage.xpak.xsplit_mem(xpak_data)
@@ -716,7 +690,7 @@ def dir_get_metadata(baseurl, conn=None, chunk_size=3000, verbose=1, usingcache=
break
# We may have metadata... now we run through the tbz2 list and check.
- class CacheStats(object):
+ class CacheStats:
from time import time
def __init__(self, out):
self.misses = 0
@@ -820,12 +794,11 @@ def _cmp_cpv(d1, d2):
cpv2 = d2["CPV"]
if cpv1 > cpv2:
return 1
- elif cpv1 == cpv2:
+ if cpv1 == cpv2:
return 0
- else:
- return -1
+ return -1
-class PackageIndex(object):
+class PackageIndex:
def __init__(self,
allowed_pkg_keys=None,
@@ -911,7 +884,7 @@ class PackageIndex(object):
def write(self, pkgfile):
if self.modified:
- self.header["TIMESTAMP"] = str(long(time.time()))
+ self.header["TIMESTAMP"] = str(int(time.time()))
self.header["PACKAGES"] = str(len(self.packages))
keys = list(self.header)
keys.sort()
diff --git a/lib/portage/glsa.py b/lib/portage/glsa.py
index 3fd877b22..4066d6747 100644
--- a/lib/portage/glsa.py
+++ b/lib/portage/glsa.py
@@ -1,14 +1,11 @@
# Copyright 2003-2017 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
import io
import sys
-try:
- from urllib.request import urlopen as urllib_request_urlopen
-except ImportError:
- from urllib import urlopen as urllib_request_urlopen
+from urllib.request import urlopen as urllib_request_urlopen
import codecs
import re
import operator
@@ -142,7 +139,7 @@ def getListElements(listnode):
if li.nodeType == xml.dom.Node.ELEMENT_NODE]
return rValue
-def getText(node, format, textfd = None):
+def getText(node, format, textfd = None): # pylint: disable=redefined-builtin
"""
This is the main parser function. It takes a node and traverses
recursive over the subnodes, getting the text of each (and the
@@ -213,7 +210,7 @@ def getText(node, format, textfd = None):
rValue = re.sub(r"[\s]{2,}", " ", rValue)
return rValue
-def getMultiTagsText(rootnode, tagname, format):
+def getMultiTagsText(rootnode, tagname, format): # pylint: disable=redefined-builtin
"""
Returns a list with the text of all subnodes of type I{tagname}
under I{rootnode} (which itself is not parsed) using the given I{format}.
@@ -296,10 +293,9 @@ def match(atom, dbapi, match_type="default"):
"""
if atom[2] == "~":
return revisionMatch(atom, dbapi, match_type=match_type)
- elif match_type == "default" or not hasattr(dbapi, "xmatch"):
+ if match_type == "default" or not hasattr(dbapi, "xmatch"):
return dbapi.match(atom)
- else:
- return dbapi.xmatch(match_type, atom)
+ return dbapi.xmatch(match_type, atom)
def revisionMatch(revisionAtom, dbapi, match_type="default"):
"""
diff --git a/lib/portage/locks.py b/lib/portage/locks.py
index 535698dfe..a0981712e 100644
--- a/lib/portage/locks.py
+++ b/lib/portage/locks.py
@@ -23,9 +23,6 @@ from portage.util import writemsg
from portage.util.install_mask import _raise_exc
from portage.localization import _
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
HARDLINK_FD = -2
_HARDLINK_POLL_LATENCY = 3 # seconds
@@ -87,7 +84,7 @@ def _get_lock_fn():
_open_fds = {}
_open_inodes = {}
-class _lock_manager(object):
+class _lock_manager:
__slots__ = ('fd', 'inode_key')
def __init__(self, fd, fstat_result, path):
self.fd = fd
@@ -167,7 +164,7 @@ def _lockfile_iteration(mypath, wantnewlockfile=False, unlinkfile=False,
# deprecated due to ambiguity in whether or not it's safe to close
# the file descriptor, making it prone to "Bad file descriptor" errors
# or file descriptor leaks.
- if isinstance(mypath, basestring) and mypath[-1] == '/':
+ if isinstance(mypath, str) and mypath[-1] == '/':
mypath = mypath[:-1]
lockfilename_path = mypath
@@ -192,7 +189,7 @@ def _lockfile_iteration(mypath, wantnewlockfile=False, unlinkfile=False,
else:
lockfilename = mypath
- if isinstance(mypath, basestring):
+ if isinstance(mypath, str):
if not os.path.exists(os.path.dirname(mypath)):
raise DirectoryNotFound(os.path.dirname(mypath))
preexisting = os.path.exists(lockfilename)
@@ -218,14 +215,13 @@ def _lockfile_iteration(mypath, wantnewlockfile=False, unlinkfile=False,
if e.errno in (errno.ENOENT, errno.ESTALE):
os.close(myfd)
return None
- else:
- writemsg("%s: chown('%s', -1, %d)\n" % \
- (e, lockfilename, portage_gid), noiselevel=-1)
- writemsg(_("Cannot chown a lockfile: '%s'\n") % \
- lockfilename, noiselevel=-1)
- writemsg(_("Group IDs of current user: %s\n") % \
- " ".join(str(n) for n in os.getgroups()),
- noiselevel=-1)
+ writemsg("%s: chown('%s', -1, %d)\n" % \
+ (e, lockfilename, portage_gid), noiselevel=-1)
+ writemsg(_("Cannot chown a lockfile: '%s'\n") % \
+ lockfilename, noiselevel=-1)
+ writemsg(_("Group IDs of current user: %s\n") % \
+ " ".join(str(n) for n in os.getgroups()),
+ noiselevel=-1)
finally:
os.umask(old_mask)
@@ -306,7 +302,7 @@ def _lockfile_iteration(mypath, wantnewlockfile=False, unlinkfile=False,
os.close(myfd)
lockfilename_path = _unicode_decode(lockfilename_path,
encoding=_encodings['fs'], errors='strict')
- if not isinstance(lockfilename_path, basestring):
+ if not isinstance(lockfilename_path, str):
raise
link_success = hardlink_lockfile(lockfilename_path,
waiting_msg=waiting_msg, flags=flags)
@@ -319,7 +315,7 @@ def _lockfile_iteration(mypath, wantnewlockfile=False, unlinkfile=False,
raise
fstat_result = None
- if isinstance(lockfilename, basestring) and myfd != HARDLINK_FD and unlinkfile:
+ if isinstance(lockfilename, str) and myfd != HARDLINK_FD and unlinkfile:
try:
(removed, fstat_result) = _lockfile_was_removed(myfd, lockfilename)
except Exception:
@@ -333,17 +329,6 @@ def _lockfile_iteration(mypath, wantnewlockfile=False, unlinkfile=False,
return None
if myfd != HARDLINK_FD:
-
- # FD_CLOEXEC is enabled by default in Python >=3.4.
- if sys.hexversion < 0x3040000:
- try:
- fcntl.FD_CLOEXEC
- except AttributeError:
- pass
- else:
- fcntl.fcntl(myfd, fcntl.F_SETFD,
- fcntl.fcntl(myfd, fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
-
_lock_manager(myfd, os.fstat(myfd) if fstat_result is None else fstat_result, mypath)
writemsg(str((lockfilename, myfd, unlinkfile)) + "\n", 1)
@@ -461,7 +446,7 @@ def unlockfile(mytuple):
return True
# myfd may be None here due to myfd = mypath in lockfile()
- if isinstance(lockfilename, basestring) and \
+ if isinstance(lockfilename, str) and \
not os.path.exists(lockfilename):
writemsg(_("lockfile does not exist '%s'\n") % lockfilename, 1)
if myfd is not None:
@@ -474,7 +459,7 @@ def unlockfile(mytuple):
unlinkfile = 1
locking_method(myfd, fcntl.LOCK_UN)
except OSError:
- if isinstance(lockfilename, basestring):
+ if isinstance(lockfilename, str):
_open_fds[myfd].close()
raise IOError(_("Failed to unlock file '%s'\n") % lockfilename)
@@ -507,7 +492,7 @@ def unlockfile(mytuple):
# why test lockfilename? because we may have been handed an
# fd originally, and the caller might not like having their
# open fd closed automatically on them.
- if isinstance(lockfilename, basestring):
+ if isinstance(lockfilename, str):
_open_fds[myfd].close()
return True
@@ -731,4 +716,3 @@ def hardlock_cleanup(path, remove_all_locks=False):
pass
return results
-
diff --git a/lib/portage/mail.py b/lib/portage/mail.py
index 11923eea6..df7aac52d 100644
--- a/lib/portage/mail.py
+++ b/lib/portage/mail.py
@@ -1,4 +1,4 @@
-# Copyright 1998-2014 Gentoo Foundation
+# Copyright 1998-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# Since python ebuilds remove the 'email' module when USE=build
@@ -19,23 +19,15 @@ from portage import _unicode_decode, _unicode_encode
from portage.localization import _
import portage
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
+def _force_ascii_if_necessary(s):
+ # Force ascii encoding in order to avoid UnicodeEncodeError
+ # from smtplib.sendmail with python3 (bug #291331).
+ s = _unicode_encode(s,
+ encoding='ascii', errors='backslashreplace')
+ s = _unicode_decode(s,
+ encoding='ascii', errors='replace')
+ return s
- def _force_ascii_if_necessary(s):
- # Force ascii encoding in order to avoid UnicodeEncodeError
- # from smtplib.sendmail with python3 (bug #291331).
- s = _unicode_encode(s,
- encoding='ascii', errors='backslashreplace')
- s = _unicode_decode(s,
- encoding='ascii', errors='replace')
- return s
-
-else:
-
- def _force_ascii_if_necessary(s):
- return s
def TextMessage(_text):
from email.mime.text import MIMEText
@@ -50,16 +42,6 @@ def create_message(sender, recipient, subject, body, attachments=None):
from email.mime.multipart import MIMEMultipart as MultipartMessage
from email.utils import formatdate
- if sys.hexversion < 0x3000000:
- sender = _unicode_encode(sender,
- encoding=_encodings['content'], errors='strict')
- recipient = _unicode_encode(recipient,
- encoding=_encodings['content'], errors='strict')
- subject = _unicode_encode(subject,
- encoding=_encodings['content'], errors='backslashreplace')
- body = _unicode_encode(body,
- encoding=_encodings['content'], errors='backslashreplace')
-
if attachments == None:
mymessage = TextMessage(body)
else:
@@ -68,11 +50,7 @@ def create_message(sender, recipient, subject, body, attachments=None):
for x in attachments:
if isinstance(x, BaseMessage):
mymessage.attach(x)
- elif isinstance(x, basestring):
- if sys.hexversion < 0x3000000:
- x = _unicode_encode(x,
- encoding=_encodings['content'],
- errors='backslashreplace')
+ elif isinstance(x, str):
mymessage.attach(TextMessage(x))
else:
raise portage.exception.PortageException(_("Can't handle type of attachment: %s") % type(x))
@@ -132,20 +110,6 @@ def send_mail(mysettings, message):
myfrom = message.get("From")
- if sys.hexversion < 0x3000000:
- myrecipient = _unicode_encode(myrecipient,
- encoding=_encodings['content'], errors='strict')
- mymailhost = _unicode_encode(mymailhost,
- encoding=_encodings['content'], errors='strict')
- mymailport = _unicode_encode(mymailport,
- encoding=_encodings['content'], errors='strict')
- myfrom = _unicode_encode(myfrom,
- encoding=_encodings['content'], errors='strict')
- mymailuser = _unicode_encode(mymailuser,
- encoding=_encodings['content'], errors='strict')
- mymailpasswd = _unicode_encode(mymailpasswd,
- encoding=_encodings['content'], errors='strict')
-
# user wants to use a sendmail binary instead of smtp
if mymailhost[0] == os.sep and os.path.exists(mymailhost):
fd = os.popen(mymailhost+" -f "+myfrom+" "+myrecipient, "w")
@@ -174,4 +138,3 @@ def send_mail(mysettings, message):
except socket.error as e:
raise portage.exception.PortageException(_("!!! A network error occurred while trying to send logmail:\n%s\nSure you configured PORTAGE_ELOG_MAILURI correctly?") % str(e))
return
-
diff --git a/lib/portage/manifest.py b/lib/portage/manifest.py
index 4bca61e86..79c756f04 100644
--- a/lib/portage/manifest.py
+++ b/lib/portage/manifest.py
@@ -1,14 +1,11 @@
-# Copyright 1999-2016 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import errno
import io
import logging
import re
import stat
-import sys
import warnings
import portage
@@ -33,12 +30,6 @@ _manifest_re = re.compile(
r'^(' + '|'.join(MANIFEST2_IDENTIFIERS) + r') (\S+)( \d+( \S+ \S+)+)$',
re.UNICODE)
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- _unicode = str
- basestring = str
-else:
- _unicode = unicode
class FileNotInManifestException(PortageException):
pass
@@ -62,21 +53,20 @@ def guessManifestFileType(filename):
return None
if filename.startswith("files" + os.sep):
return "AUX"
- elif filename.endswith(".ebuild"):
+ if filename.endswith(".ebuild"):
return "EBUILD"
- elif filename in ["ChangeLog", "metadata.xml"]:
+ if filename in ["ChangeLog", "metadata.xml"]:
return "MISC"
- else:
- return "DIST"
+ return "DIST"
def guessThinManifestFileType(filename):
- type = guessManifestFileType(filename)
- if type != "DIST":
+ filetype = guessManifestFileType(filename)
+ if filetype != "DIST":
return None
return "DIST"
def parseManifest2(line):
- if not isinstance(line, basestring):
+ if not isinstance(line, str):
line = ' '.join(line)
myentry = None
match = _manifest_re.match(line)
@@ -88,7 +78,7 @@ def parseManifest2(line):
name=match.group(2), hashes=hashes)
return myentry
-class ManifestEntry(object):
+class ManifestEntry:
__slots__ = ("type", "name", "hashes")
def __init__(self, **kwargs):
for k, v in kwargs.items():
@@ -115,15 +105,8 @@ class Manifest2Entry(ManifestEntry):
def __ne__(self, other):
return not self.__eq__(other)
- if sys.hexversion < 0x3000000:
-
- __unicode__ = __str__
-
- def __str__(self):
- return _unicode_encode(self.__unicode__(),
- encoding=_encodings['repo.content'], errors='strict')
-class Manifest(object):
+class Manifest:
parsers = (parseManifest2,)
def __init__(self, pkgdir, distdir=None, fetchlist_dict=None,
manifest1_compat=DeprecationWarning, from_scratch=False, thin=False,
@@ -321,7 +304,7 @@ class Manifest(object):
# thin manifests with no DIST entries, myentries is
# non-empty for all currently known use cases.
write_atomic(self.getFullname(), "".join("%s\n" %
- _unicode(myentry) for myentry in myentries))
+ str(myentry) for myentry in myentries))
self._apply_max_mtime(preserved_stats, myentries)
rval = True
else:
diff --git a/lib/portage/metadata.py b/lib/portage/metadata.py
index ffb7672d3..935bcc307 100644
--- a/lib/portage/metadata.py
+++ b/lib/portage/metadata.py
@@ -32,7 +32,7 @@ def action_metadata(settings, portdb, myopts, porttrees=None):
auxdbkeys = portdb._known_keys
- class TreeData(object):
+ class TreeData:
__slots__ = ('dest_db', 'eclass_db', 'path', 'src_db', 'valid_nodes')
def __init__(self, dest_db, eclass_db, path, src_db):
self.dest_db = dest_db
diff --git a/lib/portage/module.py b/lib/portage/module.py
index bd7c94d4e..301bfbdba 100644
--- a/lib/portage/module.py
+++ b/lib/portage/module.py
@@ -19,7 +19,7 @@ class ModuleVersionError(PortageException):
'''An incompatible module version'''
-class Module(object):
+class Module:
"""Class to define and hold our plug-in module
@type name: string
@@ -83,7 +83,7 @@ class Module(object):
return mod_class
-class Modules(object):
+class Modules:
"""Dynamic modules system for loading and retrieving any of the
installed emaint modules and/or provided class's
diff --git a/lib/portage/news.py b/lib/portage/news.py
index f7c8c7bb9..2731ea889 100644
--- a/lib/portage/news.py
+++ b/lib/portage/news.py
@@ -2,7 +2,7 @@
# Copyright 2006-2019 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
__all__ = ["NewsManager", "NewsItem", "DisplayRestriction",
"DisplayProfileRestriction", "DisplayKeywordRestriction",
@@ -32,7 +32,7 @@ from portage.output import colorize
from portage.exception import (InvalidLocation, OperationNotPermitted,
PermissionDenied, ReadOnlyFileSystem)
-class NewsManager(object):
+class NewsManager:
"""
This object manages GLEP 42 style news items. It will cache news items
that have previously shown up and notify users when there are relevant news
@@ -200,7 +200,7 @@ _profileRE = re.compile("Display-If-Profile:(.*)\n")
_keywordRE = re.compile("Display-If-Keyword:(.*)\n")
_valid_profile_RE = re.compile(r'^[^*]+(/\*)?$')
-class NewsItem(object):
+class NewsItem:
"""
This class encapsulates a GLEP 42 style news item.
It's purpose is to wrap parsing of these news items such that portage can determine
@@ -313,7 +313,7 @@ class NewsItem(object):
self._parsed = True
-class DisplayRestriction(object):
+class DisplayRestriction:
"""
A base restriction object representing a restriction of display.
news items may have 'relevancy restrictions' preventing them from
diff --git a/lib/portage/output.py b/lib/portage/output.py
index 1070d0ef3..4c8f8a187 100644
--- a/lib/portage/output.py
+++ b/lib/portage/output.py
@@ -1,4 +1,4 @@
-# Copyright 1998-2015 Gentoo Foundation
+# Copyright 1998-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
from __future__ import division
@@ -234,7 +234,7 @@ def nc_len(mystr):
tmp = re.sub(esc_seq + "^m]+m", "", mystr);
return len(tmp)
-_legal_terms_re = re.compile(r'^(xterm|xterm-color|Eterm|aterm|rxvt|screen|kterm|rxvt-unicode|gnome|interix|tmux|st-256color)')
+_legal_terms_re = re.compile(r'^(xterm|xterm-color|Eterm|aterm|rxvt|screen|kterm|rxvt-unicode|gnome|interix|tmux|st-256color|alacritty|konsole)')
_disable_xtermTitle = None
_max_xtermTitle_len = 253
@@ -256,9 +256,7 @@ def xtermTitle(mystr, raw=False):
# avoid potential UnicodeEncodeError
mystr = _unicode_encode(mystr,
encoding=_encodings['stdio'], errors='backslashreplace')
- f = sys.stderr
- if sys.hexversion >= 0x3000000:
- f = f.buffer
+ f = sys.stderr.buffer
f.write(mystr)
f.flush()
@@ -336,12 +334,9 @@ def colorize(color_key, text):
if havecolor:
if color_key in codes:
return codes[color_key] + text + codes["reset"]
- elif color_key in _styles:
+ if color_key in _styles:
return style_to_ansi_code(color_key) + text + codes["reset"]
- else:
- return text
- else:
- return text
+ return text
compat_functions_colors = [
"bold", "white", "teal", "turquoise", "darkteal",
@@ -349,7 +344,7 @@ compat_functions_colors = [
"brown", "darkyellow", "red", "darkred",
]
-class create_color_func(object):
+class create_color_func:
__slots__ = ("_color_key",)
def __init__(self, color_key):
self._color_key = color_key
@@ -359,7 +354,7 @@ class create_color_func(object):
for c in compat_functions_colors:
globals()[c] = create_color_func(c)
-class ConsoleStyleFile(object):
+class ConsoleStyleFile:
"""
A file-like object that behaves something like
the colorize() function. Style identifiers
@@ -398,8 +393,7 @@ class ConsoleStyleFile(object):
if f in (sys.stdout, sys.stderr):
s = _unicode_encode(s,
encoding=_encodings['stdio'], errors='backslashreplace')
- if sys.hexversion >= 0x3000000:
- f = f.buffer
+ f = f.buffer
f.write(s)
def writelines(self, lines):
@@ -485,7 +479,7 @@ def set_term_size(lines, columns, fd):
except CommandNotFound:
writemsg(_("portage: stty: command not found\n"), noiselevel=-1)
-class EOutput(object):
+class EOutput:
"""
Performs fancy terminal formatting for status and informational messages.
@@ -643,7 +637,7 @@ class EOutput(object):
self.__eend("ewend", errno, msg)
self.__last_e_cmd = "ewend"
-class ProgressBar(object):
+class ProgressBar:
"""The interface is copied from the ProgressBar class from the EasyDialogs
module (which is Mac only)."""
def __init__(self, title=None, maxval=0, label=None, max_desc_length=25):
@@ -755,6 +749,7 @@ class TermProgressBar(ProgressBar):
bar_space = cols - percentage_str_width - square_brackets_width - 1
if self._desc:
bar_space -= self._desc_max_length
+
if maxval == 0:
max_bar_width = bar_space-3
_percent = "".ljust(percentage_str_width)
@@ -779,19 +774,19 @@ class TermProgressBar(ProgressBar):
"[" + (bar_width * " ") + \
"<=>" + ((max_bar_width - bar_width) * " ") + "]")
return image
- else:
- percentage = 100 * curval // maxval
- max_bar_width = bar_space - 1
- _percent = ("%d%% " % percentage).rjust(percentage_str_width)
- image = "%s%s" % (self._desc, _percent)
- if cols < min_columns:
- return image
- offset = curval / maxval
- bar_width = int(offset * max_bar_width)
- image = image + "[" + (bar_width * "=") + \
- ">" + ((max_bar_width - bar_width) * " ") + "]"
+ percentage = 100 * curval // maxval
+ max_bar_width = bar_space - 1
+ _percent = ("%d%% " % percentage).rjust(percentage_str_width)
+ image = "%s%s" % (self._desc, _percent)
+
+ if cols < min_columns:
return image
+ offset = curval / maxval
+ bar_width = int(offset * max_bar_width)
+ image = image + "[" + (bar_width * "=") + \
+ ">" + ((max_bar_width - bar_width) * " ") + "]"
+ return image
_color_map_loaded = False
diff --git a/lib/portage/package/ebuild/_config/KeywordsManager.py b/lib/portage/package/ebuild/_config/KeywordsManager.py
index 48397b022..136f57c35 100644
--- a/lib/portage/package/ebuild/_config/KeywordsManager.py
+++ b/lib/portage/package/ebuild/_config/KeywordsManager.py
@@ -16,7 +16,7 @@ from portage.package.ebuild._config.helper import ordered_by_atom_specificity
from portage.util import grabdict_package, stack_lists, writemsg
from portage.versions import _pkg_str
-class KeywordsManager(object):
+class KeywordsManager:
"""Manager class to handle keywords processing and validation"""
def __init__(self, profiles, abs_user_config, user_config=True,
diff --git a/lib/portage/package/ebuild/_config/LicenseManager.py b/lib/portage/package/ebuild/_config/LicenseManager.py
index 1d4e08207..fcffdb12e 100644
--- a/lib/portage/package/ebuild/_config/LicenseManager.py
+++ b/lib/portage/package/ebuild/_config/LicenseManager.py
@@ -15,7 +15,7 @@ from portage.versions import cpv_getkey, _pkg_str
from portage.package.ebuild._config.helper import ordered_by_atom_specificity
-class LicenseManager(object):
+class LicenseManager:
def __init__(self, license_group_locations, abs_user_config, user_config=True):
diff --git a/lib/portage/package/ebuild/_config/LocationsManager.py b/lib/portage/package/ebuild/_config/LocationsManager.py
index 75320258f..b90b9227c 100644
--- a/lib/portage/package/ebuild/_config/LocationsManager.py
+++ b/lib/portage/package/ebuild/_config/LocationsManager.py
@@ -1,8 +1,6 @@
# Copyright 2010-2018 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
__all__ = (
'LocationsManager',
)
@@ -37,7 +35,7 @@ _profile_node = collections.namedtuple('_profile_node',
_allow_parent_colon = frozenset(
["portage-2"])
-class LocationsManager(object):
+class LocationsManager:
def __init__(self, config_root=None, eprefix=None, config_profile_path=None, local_config=True, \
target_root=None, sysroot=None):
diff --git a/lib/portage/package/ebuild/_config/MaskManager.py b/lib/portage/package/ebuild/_config/MaskManager.py
index 40cc6e0c4..7714456e1 100644
--- a/lib/portage/package/ebuild/_config/MaskManager.py
+++ b/lib/portage/package/ebuild/_config/MaskManager.py
@@ -13,7 +13,7 @@ from portage.localization import _
from portage.util import append_repo, grabfile_package, stack_lists, writemsg
from portage.versions import _pkg_str
-class MaskManager(object):
+class MaskManager:
def __init__(self, repositories, profiles, abs_user_config,
user_config=True, strict_umatched_removal=False):
diff --git a/lib/portage/package/ebuild/_config/UseManager.py b/lib/portage/package/ebuild/_config/UseManager.py
index 7302876ab..190ab1b7c 100644
--- a/lib/portage/package/ebuild/_config/UseManager.py
+++ b/lib/portage/package/ebuild/_config/UseManager.py
@@ -16,7 +16,7 @@ from portage.versions import _pkg_str
from portage.package.ebuild._config.helper import ordered_by_atom_specificity
-class UseManager(object):
+class UseManager:
def __init__(self, repositories, profiles, abs_user_config, is_stable,
user_config=True):
diff --git a/lib/portage/package/ebuild/_config/VirtualsManager.py b/lib/portage/package/ebuild/_config/VirtualsManager.py
index c4d1e3635..a08c969ac 100644
--- a/lib/portage/package/ebuild/_config/VirtualsManager.py
+++ b/lib/portage/package/ebuild/_config/VirtualsManager.py
@@ -14,7 +14,7 @@ from portage.localization import _
from portage.util import grabdict, stack_dictlist, writemsg
from portage.versions import cpv_getkey
-class VirtualsManager(object):
+class VirtualsManager:
def __init__(self, *args, **kwargs):
if kwargs.get("_copy"):
diff --git a/lib/portage/package/ebuild/_config/features_set.py b/lib/portage/package/ebuild/_config/features_set.py
index 62236fd89..d38874379 100644
--- a/lib/portage/package/ebuild/_config/features_set.py
+++ b/lib/portage/package/ebuild/_config/features_set.py
@@ -12,7 +12,7 @@ from portage.localization import _
from portage.output import colorize
from portage.util import writemsg_level
-class features_set(object):
+class features_set:
"""
Provides relevant set operations needed for access and modification of
config.features. The FEATURES variable is automatically synchronized
diff --git a/lib/portage/package/ebuild/_config/special_env_vars.py b/lib/portage/package/ebuild/_config/special_env_vars.py
index 12d701c9a..8a9161c1b 100644
--- a/lib/portage/package/ebuild/_config/special_env_vars.py
+++ b/lib/portage/package/ebuild/_config/special_env_vars.py
@@ -1,8 +1,6 @@
-# Copyright 2010-2019 Gentoo Authors
+# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
__all__ = (
'case_insensitive_vars', 'default_globals', 'env_blacklist', \
'environ_filter', 'environ_whitelist', 'environ_whitelist_re',
@@ -184,7 +182,7 @@ environ_filter += [
"PORTAGE_RO_DISTDIRS",
"PORTAGE_RSYNC_EXTRA_OPTS", "PORTAGE_RSYNC_OPTS",
"PORTAGE_RSYNC_RETRIES", "PORTAGE_SSH_OPTS", "PORTAGE_SYNC_STALE",
- "PORTAGE_USE",
+ "PORTAGE_USE", "PORTAGE_LOG_FILTER_FILE_CMD",
"PORTAGE_LOGDIR", "PORTAGE_LOGDIR_CLEAN",
"QUICKPKG_DEFAULT_OPTS", "REPOMAN_DEFAULT_OPTS",
"RESUMECOMMAND", "RESUMECOMMAND_FTP",
@@ -213,7 +211,9 @@ default_globals = {
'PORTAGE_BZIP2_COMMAND': 'bzip2',
}
-validate_commands = ('PORTAGE_BZIP2_COMMAND', 'PORTAGE_BUNZIP2_COMMAND',)
+validate_commands = ('PORTAGE_BZIP2_COMMAND', 'PORTAGE_BUNZIP2_COMMAND',
+ 'PORTAGE_LOG_FILTER_FILE_CMD',
+)
# To enhance usability, make some vars case insensitive
# by forcing them to lower case.
diff --git a/lib/portage/package/ebuild/_ipc/IpcCommand.py b/lib/portage/package/ebuild/_ipc/IpcCommand.py
index efb27f0a2..42a612753 100644
--- a/lib/portage/package/ebuild/_ipc/IpcCommand.py
+++ b/lib/portage/package/ebuild/_ipc/IpcCommand.py
@@ -1,7 +1,7 @@
# Copyright 2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-class IpcCommand(object):
+class IpcCommand:
__slots__ = ()
diff --git a/lib/portage/package/ebuild/_ipc/QueryCommand.py b/lib/portage/package/ebuild/_ipc/QueryCommand.py
index fa6d1ea16..7af465234 100644
--- a/lib/portage/package/ebuild/_ipc/QueryCommand.py
+++ b/lib/portage/package/ebuild/_ipc/QueryCommand.py
@@ -1,8 +1,6 @@
# Copyright 2010-2018 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import io
import portage
@@ -84,10 +82,10 @@ class QueryCommand(IpcCommand):
else:
returncode = 1
return ('', warnings_str, returncode)
- elif cmd == 'best_version':
+ if cmd == 'best_version':
m = best(vardb.match(atom))
return ('%s\n' % m, warnings_str, 0)
- elif cmd in ('master_repositories', 'repository_path', 'available_eclasses', 'eclass_path', 'license_path'):
+ if cmd in ('master_repositories', 'repository_path', 'available_eclasses', 'eclass_path', 'license_path'):
repo = _repo_name_re.match(args[0])
if repo is None:
return ('', '%s: Invalid repository: %s\n' % (cmd, args[0]), 2)
@@ -98,24 +96,23 @@ class QueryCommand(IpcCommand):
if cmd == 'master_repositories':
return ('%s\n' % ' '.join(x.name for x in repo.masters), warnings_str, 0)
- elif cmd == 'repository_path':
+ if cmd == 'repository_path':
return ('%s\n' % repo.location, warnings_str, 0)
- elif cmd == 'available_eclasses':
+ if cmd == 'available_eclasses':
return ('%s\n' % ' '.join(sorted(repo.eclass_db.eclasses)), warnings_str, 0)
- elif cmd == 'eclass_path':
+ if cmd == 'eclass_path':
try:
eclass = repo.eclass_db.eclasses[args[1]]
except KeyError:
return ('', warnings_str, 1)
return ('%s\n' % eclass.location, warnings_str, 0)
- elif cmd == 'license_path':
+ if cmd == 'license_path':
paths = reversed([os.path.join(x.location, 'licenses', args[1]) for x in list(repo.masters) + [repo]])
for path in paths:
if os.path.exists(path):
return ('%s\n' % path, warnings_str, 0)
return ('', warnings_str, 1)
- else:
- return ('', 'Invalid command: %s\n' % cmd, 3)
+ return ('', 'Invalid command: %s\n' % cmd, 3)
def _elog(self, elog_funcname, lines):
"""
diff --git a/lib/portage/package/ebuild/_parallel_manifest/ManifestProcess.py b/lib/portage/package/ebuild/_parallel_manifest/ManifestProcess.py
index 44e257664..cf718a796 100644
--- a/lib/portage/package/ebuild/_parallel_manifest/ManifestProcess.py
+++ b/lib/portage/package/ebuild/_parallel_manifest/ManifestProcess.py
@@ -39,5 +39,4 @@ class ManifestProcess(ForkProcess):
else:
if modified:
return self.MODIFIED
- else:
- return os.EX_OK
+ return os.EX_OK
diff --git a/lib/portage/package/ebuild/_parallel_manifest/ManifestScheduler.py b/lib/portage/package/ebuild/_parallel_manifest/ManifestScheduler.py
index fabea9bc1..2ac736bc6 100644
--- a/lib/portage/package/ebuild/_parallel_manifest/ManifestScheduler.py
+++ b/lib/portage/package/ebuild/_parallel_manifest/ManifestScheduler.py
@@ -84,5 +84,3 @@ class ManifestScheduler(AsyncScheduler):
noiselevel=-1)
AsyncScheduler._task_exit(self, task)
-
-
diff --git a/lib/portage/package/ebuild/config.py b/lib/portage/package/ebuild/config.py
index c76474354..b1b2b47d7 100644
--- a/lib/portage/package/ebuild/config.py
+++ b/lib/portage/package/ebuild/config.py
@@ -1,8 +1,6 @@
-# Copyright 2010-2019 Gentoo Authors
+# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
__all__ = [
'autouse', 'best_from_dict', 'check_config_instance', 'config',
]
@@ -68,9 +66,6 @@ from portage.package.ebuild._config.VirtualsManager import VirtualsManager
from portage.package.ebuild._config.helper import ordered_by_atom_specificity, prune_incremental
from portage.package.ebuild._config.unpack_dependencies import load_unpack_dependencies_configuration
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
_feature_flags_cache = {}
@@ -102,12 +97,10 @@ def best_from_dict(key, top_dict, key_order, EmptyOnError=1, FullCopy=1, AllowEm
if x in top_dict and key in top_dict[x]:
if FullCopy:
return copy.deepcopy(top_dict[x][key])
- else:
- return top_dict[x][key]
+ return top_dict[x][key]
if EmptyOnError:
return ""
- else:
- raise KeyError("Key not found in list; '%s'" % key)
+ raise KeyError("Key not found in list; '%s'" % key)
def _lazy_iuse_regex(iuse_implicit):
"""
@@ -122,7 +115,7 @@ def _lazy_iuse_regex(iuse_implicit):
regex = regex.replace("\\.\\*", ".*")
return regex
-class _iuse_implicit_match_cache(object):
+class _iuse_implicit_match_cache:
def __init__(self, settings):
self._iuse_implicit_re = re.compile("^(%s)$" % \
@@ -140,7 +133,7 @@ class _iuse_implicit_match_cache(object):
self._cache[flag] = m
return m
-class config(object):
+class config:
"""
This class encompasses the main portage configuration. Data is pulled from
ROOT/PORTDIR/profiles/, from ROOT/etc/make.profile incrementally through all
@@ -1324,7 +1317,7 @@ class config(object):
self.useforce = self._use_manager.getUseForce()
self.regenerate()
- class _lazy_vars(object):
+ class _lazy_vars:
__slots__ = ('built_use', 'settings', 'values')
@@ -1357,7 +1350,7 @@ class config(object):
restrict = set()
return ' '.join(sorted(restrict))
- class _lazy_use_expand(object):
+ class _lazy_use_expand:
"""
Lazily evaluate USE_EXPAND variables since they are only needed when
an ebuild shell is spawned. Variables values are made consistent with
@@ -1456,7 +1449,7 @@ class config(object):
pkg = None
built_use = None
explicit_iuse = None
- if not isinstance(mycpv, basestring):
+ if not isinstance(mycpv, str):
pkg = mycpv
mycpv = pkg.cpv
mydb = pkg._metadata
@@ -2645,10 +2638,10 @@ class config(object):
# portage plans to update itself.
if mykey == "PORTAGE_BIN_PATH":
return portage._bin_path
- elif mykey == "PORTAGE_PYM_PATH":
+ if mykey == "PORTAGE_PYM_PATH":
return portage._pym_path
- elif mykey == "PORTAGE_PYTHONPATH":
+ if mykey == "PORTAGE_PYTHONPATH":
value = [x for x in \
self.backupenv.get("PYTHONPATH", "").split(":") if x]
need_pym_path = True
@@ -2662,7 +2655,7 @@ class config(object):
value.insert(0, portage._pym_path)
return ":".join(value)
- elif mykey == "PORTAGE_GID":
+ if mykey == "PORTAGE_GID":
return "%s" % portage_gid
for d in self.lookuplist:
@@ -2705,7 +2698,7 @@ class config(object):
def __contains__(self, mykey):
"""Called to implement membership test operators (in and not in)."""
try:
- self._getitem(mykey)
+ self._getitem(mykey)
except KeyError:
return False
else:
@@ -2715,12 +2708,8 @@ class config(object):
v = self.get(k)
if v is not None:
return v
- else:
- self[k] = x
- return x
-
- def keys(self):
- return list(self)
+ self[k] = x
+ return x
def __iter__(self):
keys = set()
@@ -2736,12 +2725,9 @@ class config(object):
for k in self:
yield (k, self._getitem(k))
- def items(self):
- return list(self.iteritems())
-
def __setitem__(self,mykey,myvalue):
"set a value; will be thrown away at reset() time"
- if not isinstance(myvalue, basestring):
+ if not isinstance(myvalue, str):
raise ValueError("Invalid type being used as a value: '%s': '%s'" % (str(mykey),str(myvalue)))
# Avoid potential UnicodeDecodeError exceptions later.
@@ -2774,7 +2760,7 @@ class config(object):
for x, myvalue in self.iteritems():
if x in environ_filter:
continue
- if not isinstance(myvalue, basestring):
+ if not isinstance(myvalue, str):
writemsg(_("!!! Non-string value in config: %s=%s\n") % \
(x, myvalue), noiselevel=-1)
continue
@@ -2929,6 +2915,5 @@ class config(object):
return self._selinux_enabled
- if sys.hexversion >= 0x3000000:
- keys = __iter__
- items = iteritems
+ keys = __iter__
+ items = iteritems
diff --git a/lib/portage/package/ebuild/doebuild.py b/lib/portage/package/ebuild/doebuild.py
index 7d685dbe4..1a667a03d 100644
--- a/lib/portage/package/ebuild/doebuild.py
+++ b/lib/portage/package/ebuild/doebuild.py
@@ -1,8 +1,6 @@
# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
__all__ = ['doebuild', 'doebuild_environment', 'spawn', 'spawnebuild']
import grp
@@ -95,10 +93,6 @@ from _emerge.EbuildSpawnProcess import EbuildSpawnProcess
from _emerge.Package import Package
from _emerge.RootConfig import RootConfig
-if sys.hexversion >= 0x3000000:
- _unicode = str
-else:
- _unicode = unicode
_unsandboxed_phases = frozenset([
"clean", "cleanrm", "config",
@@ -851,7 +845,7 @@ def doebuild(myebuild, mydo, _unused=DeprecationWarning, settings=None, debug=0,
if returnpid:
return _spawn_phase(mydo, mysettings,
fd_pipes=fd_pipes, returnpid=returnpid)
- elif dbkey and dbkey is not DeprecationWarning:
+ if dbkey and dbkey is not DeprecationWarning:
mysettings["dbkey"] = dbkey
else:
mysettings["dbkey"] = \
@@ -860,7 +854,7 @@ def doebuild(myebuild, mydo, _unused=DeprecationWarning, settings=None, debug=0,
return _spawn_phase(mydo, mysettings,
fd_pipes=fd_pipes, returnpid=returnpid)
- elif mydo == "nofetch":
+ if mydo == "nofetch":
if returnpid:
writemsg("!!! doebuild: %s\n" %
@@ -1140,11 +1134,11 @@ def doebuild(myebuild, mydo, _unused=DeprecationWarning, settings=None, debug=0,
mf = None
_doebuild_manifest_cache = None
return not digestgen(mysettings=mysettings, myportdb=mydbapi)
- elif mydo == "digest":
+ if mydo == "digest":
mf = None
_doebuild_manifest_cache = None
return not digestgen(mysettings=mysettings, myportdb=mydbapi)
- elif "digest" in mysettings.features:
+ if "digest" in mysettings.features:
mf = None
_doebuild_manifest_cache = None
digestgen(mysettings=mysettings, myportdb=mydbapi)
@@ -1430,7 +1424,7 @@ def _validate_deps(mysettings, myroot, mydo, mydbapi):
mydbapi.aux_get(mysettings.mycpv, all_keys,
myrepo=mysettings.get("PORTAGE_REPO_NAME"))))
- class FakeTree(object):
+ class FakeTree:
def __init__(self, mydb):
self.dbapi = mydb
@@ -2489,7 +2483,7 @@ def _post_src_install_soname_symlinks(mysettings, out):
# Compute the multilib category and write it back to the file.
entry.multilib_category = compute_multilib_category(elf_header)
- needed_file.write(_unicode(entry))
+ needed_file.write(str(entry))
if entry.multilib_category is None:
if not qa_prebuilt or qa_prebuilt.match(
@@ -2540,7 +2534,7 @@ def _post_src_install_soname_symlinks(mysettings, out):
if unrecognized_elf_files:
qa_msg = ["QA Notice: Unrecognized ELF file(s):"]
qa_msg.append("")
- qa_msg.extend("\t%s" % _unicode(entry).rstrip()
+ qa_msg.extend("\t%s" % str(entry).rstrip()
for entry in unrecognized_elf_files)
qa_msg.append("")
for line in qa_msg:
diff --git a/lib/portage/package/ebuild/fetch.py b/lib/portage/package/ebuild/fetch.py
index 11b13fe56..5a55c4076 100644
--- a/lib/portage/package/ebuild/fetch.py
+++ b/lib/portage/package/ebuild/fetch.py
@@ -20,16 +20,8 @@ import tempfile
import time
from collections import OrderedDict
-
-try:
- from urllib.parse import urlparse
-except ImportError:
- from urlparse import urlparse
-
-try:
- from urllib.parse import quote as urlquote
-except ImportError:
- from urllib import quote as urlquote
+from urllib.parse import urlparse
+from urllib.parse import quote as urlquote
import portage
portage.proxy.lazyimport.lazyimport(globals(),
@@ -355,7 +347,7 @@ _size_suffix_map = {
}
-class FlatLayout(object):
+class FlatLayout:
def get_path(self, filename):
return filename
@@ -375,7 +367,7 @@ class FlatLayout(object):
return len(args) == 1
-class FilenameHashLayout(object):
+class FilenameHashLayout:
def __init__(self, algo, cutoffs):
self.algo = algo
self.cutoffs = [int(x) for x in cutoffs.split(':')]
@@ -424,7 +416,7 @@ class FilenameHashLayout(object):
return False
-class MirrorLayoutConfig(object):
+class MirrorLayoutConfig:
"""
Class to read layout.conf from a mirror.
"""
@@ -462,11 +454,10 @@ class MirrorLayoutConfig(object):
if self.validate_structure(val):
if val[0] == 'flat':
return FlatLayout(*val[1:])
- elif val[0] == 'filename-hash':
+ if val[0] == 'filename-hash':
return FilenameHashLayout(*val[1:])
- else:
- # fallback
- return FlatLayout()
+ # fallback
+ return FlatLayout()
def get_all_layouts(self):
ret = []
@@ -1258,8 +1249,7 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0,
writemsg(_("!!! File %s is incorrect size, "
"but unable to retry.\n") % myfile, noiselevel=-1)
return 0
- else:
- continue
+ continue
if fetched != 2 and has_space:
#we either need to resume or start the download
diff --git a/lib/portage/package/ebuild/getmaskingreason.py b/lib/portage/package/ebuild/getmaskingreason.py
index 1e4ed21ce..22232de29 100644
--- a/lib/portage/package/ebuild/getmaskingreason.py
+++ b/lib/portage/package/ebuild/getmaskingreason.py
@@ -54,8 +54,7 @@ def getmaskingreason(mycpv, metadata=None, settings=None,
# contain essential things like SLOT.
if return_location:
return (None, None)
- else:
- return None
+ return None
# Sometimes we can't access SLOT or repository due to corruption.
pkg = mycpv
@@ -114,13 +113,11 @@ def getmaskingreason(mycpv, metadata=None, settings=None,
comment = ""
if return_location:
return (comment, pmask_filename)
- else:
- return comment
+ return comment
elif comment_valid != -1:
# Apparently this comment applies to multiple masks, so
# it remains valid until a blank line is encountered.
comment_valid += 1
if return_location:
return (None, None)
- else:
- return None
+ return None
diff --git a/lib/portage/package/ebuild/getmaskingstatus.py b/lib/portage/package/ebuild/getmaskingstatus.py
index 4b9e588f7..cf2b7344b 100644
--- a/lib/portage/package/ebuild/getmaskingstatus.py
+++ b/lib/portage/package/ebuild/getmaskingstatus.py
@@ -1,11 +1,8 @@
-# Copyright 2010-2014 Gentoo Foundation
+# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
__all__ = ['getmaskingstatus']
-import sys
import portage
from portage import eapi_is_supported, _eapi_is_deprecated
@@ -14,11 +11,8 @@ from portage.localization import _
from portage.package.ebuild.config import config
from portage.versions import catpkgsplit, _pkg_str
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
-class _UnmaskHint(object):
+class _UnmaskHint:
__slots__ = ('key', 'value')
@@ -26,7 +20,7 @@ class _UnmaskHint(object):
self.key = key
self.value = value
-class _MaskReason(object):
+class _MaskReason:
__slots__ = ('category', 'message', 'unmask_hint')
@@ -48,7 +42,7 @@ def _getmaskingstatus(mycpv, settings, portdb, myrepo=None):
metadata = None
installed = False
- if not isinstance(mycpv, basestring):
+ if not isinstance(mycpv, str):
# emerge passed in a Package instance
pkg = mycpv
mycpv = pkg.cpv
@@ -91,7 +85,7 @@ def _getmaskingstatus(mycpv, settings, portdb, myrepo=None):
restrict = metadata["RESTRICT"]
if not eapi_is_supported(eapi):
return [_MaskReason("EAPI", "EAPI %s" % eapi)]
- elif _eapi_is_deprecated(eapi) and not installed:
+ if _eapi_is_deprecated(eapi) and not installed:
return [_MaskReason("EAPI", "EAPI %s" % eapi)]
egroups = settings.configdict["backupenv"].get(
"ACCEPT_KEYWORDS", "").split()
diff --git a/lib/portage/package/ebuild/prepare_build_dirs.py b/lib/portage/package/ebuild/prepare_build_dirs.py
index 8349d306f..b63cd89fa 100644
--- a/lib/portage/package/ebuild/prepare_build_dirs.py
+++ b/lib/portage/package/ebuild/prepare_build_dirs.py
@@ -1,8 +1,6 @@
# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
__all__ = ['prepare_build_dirs']
import errno
diff --git a/lib/portage/process.py b/lib/portage/process.py
index 3e5d2e4ef..57f6e15a2 100644
--- a/lib/portage/process.py
+++ b/lib/portage/process.py
@@ -1,5 +1,5 @@
# portage.py -- core Portage functionality
-# Copyright 1998-2019 Gentoo Authors
+# Copyright 1998-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
@@ -40,9 +40,6 @@ try:
except ImportError:
max_fd_limit = 256
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
# Support PEP 446 for Python >=3.4
try:
@@ -112,7 +109,7 @@ def sanitize_fds():
if _set_inheritable is not None:
whitelist = frozenset([
- sys.__stdin__.fileno(),
+ portage._get_stdin().fileno(),
sys.__stdout__.fileno(),
sys.__stderr__.fileno(),
])
@@ -216,10 +213,7 @@ def run_exitfuncs():
exc_info = sys.exc_info()
if exc_info is not None:
- if sys.hexversion >= 0x3000000:
- raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
- else:
- exec("raise exc_info[0], exc_info[1], exc_info[2]")
+ raise exc_info[0](exc_info[1]).with_traceback(exc_info[2])
atexit.register(run_exitfuncs)
@@ -244,7 +238,7 @@ def cleanup():
def spawn(mycommand, env=None, opt_name=None, fd_pipes=None, returnpid=False,
uid=None, gid=None, groups=None, umask=None, cwd=None, logfile=None,
path_lookup=True, pre_exec=None,
- close_fds=(sys.version_info < (3, 4)), unshare_net=False,
+ close_fds=False, unshare_net=False,
unshare_ipc=False, unshare_mount=False, unshare_pid=False,
cgroup=None):
"""
@@ -302,20 +296,11 @@ def spawn(mycommand, env=None, opt_name=None, fd_pipes=None, returnpid=False,
"""
# mycommand is either a str or a list
- if isinstance(mycommand, basestring):
+ if isinstance(mycommand, str):
mycommand = mycommand.split()
env = os.environ if env is None else env
- if sys.hexversion < 0x3000000:
- # Avoid a potential UnicodeEncodeError from os.execve().
- env_bytes = {}
- for k, v in env.items():
- env_bytes[_unicode_encode(k, encoding=_encodings['content'])] = \
- _unicode_encode(v, encoding=_encodings['content'])
- env = env_bytes
- del env_bytes
-
# If an absolute path to an executable file isn't given
# search for it unless we've been told not to.
binary = mycommand[0]
@@ -767,7 +752,7 @@ def _exec(binary, mycommand, opt_name, fd_pipes,
os.execve(binary, myargs, env)
-class _unshare_validator(object):
+class _unshare_validator:
"""
In order to prevent failed unshare calls from corrupting the state
of an essential process, validate the relevant unshare call in a
@@ -982,7 +967,7 @@ def find_binary(binary):
@return: full path to binary or None if the binary could not be located.
"""
paths = os.environ.get("PATH", "")
- if sys.hexversion >= 0x3000000 and isinstance(binary, bytes):
+ if isinstance(binary, bytes):
# return bytes when input is bytes
paths = paths.encode(sys.getfilesystemencoding(), 'surrogateescape')
paths = paths.split(b':')
diff --git a/lib/portage/progress.py b/lib/portage/progress.py
index e43c2afbd..0be790106 100644
--- a/lib/portage/progress.py
+++ b/lib/portage/progress.py
@@ -7,7 +7,7 @@ import signal
import portage
-class ProgressHandler(object):
+class ProgressHandler:
def __init__(self):
self.reset()
@@ -58,4 +58,3 @@ class ProgressBar(ProgressHandler):
def stop(self):
signal.signal(signal.SIGWINCH, signal.SIG_DFL)
-
diff --git a/lib/portage/proxy/lazyimport.py b/lib/portage/proxy/lazyimport.py
index d4258706d..532f3ce0a 100644
--- a/lib/portage/proxy/lazyimport.py
+++ b/lib/portage/proxy/lazyimport.py
@@ -1,4 +1,4 @@
-# Copyright 2009-2014 Gentoo Foundation
+# Copyright 2009-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
__all__ = ['lazyimport']
@@ -13,9 +13,6 @@ except ImportError:
from portage.proxy.objectproxy import ObjectProxy
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
_module_proxies = {}
_module_proxies_lock = threading.RLock()
@@ -169,7 +166,7 @@ def lazyimport(scope, *args):
if len(parts) == 1:
name = s
- if not name or not isinstance(name, basestring):
+ if not name or not isinstance(name, str):
raise ValueError(name)
components = name.split('.')
diff --git a/lib/portage/proxy/objectproxy.py b/lib/portage/proxy/objectproxy.py
index a755774ae..7d03dbef6 100644
--- a/lib/portage/proxy/objectproxy.py
+++ b/lib/portage/proxy/objectproxy.py
@@ -1,11 +1,10 @@
-# Copyright 2008-2012 Gentoo Foundation
+# Copyright 2008-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-import sys
__all__ = ['ObjectProxy']
-class ObjectProxy(object):
+class ObjectProxy:
"""
Object that acts as a proxy to another object, forwarding
@@ -88,11 +87,5 @@ class ObjectProxy(object):
def __bool__(self):
return bool(object.__getattribute__(self, '_get_target')())
- if sys.hexversion < 0x3000000:
- __nonzero__ = __bool__
-
- def __unicode__(self):
- return unicode(object.__getattribute__(self, '_get_target')())
-
def __int__(self):
return int(object.__getattribute__(self, '_get_target')())
diff --git a/lib/portage/repository/config.py b/lib/portage/repository/config.py
index 50ab18026..0f3e582f8 100644
--- a/lib/portage/repository/config.py
+++ b/lib/portage/repository/config.py
@@ -1,12 +1,9 @@
-# Copyright 2010-2019 Gentoo Authors
+# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import io
import logging
import warnings
-import sys
import re
import portage
@@ -28,9 +25,6 @@ from portage import _encodings
from portage import manifest
import portage.sync
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
# Characters prohibited by repoman's file.name check.
_invalid_path_char_re = re.compile(r'[^a-zA-Z0-9._\-+/]')
@@ -71,7 +65,7 @@ def _find_invalid_path_char(path, pos=0, endpos=None):
return -1
-class RepoConfig(object):
+class RepoConfig:
"""Stores config of one repository"""
__slots__ = (
@@ -113,6 +107,7 @@ class RepoConfig(object):
'sync_hooks_only_on_change',
'sync_openpgp_keyserver',
'sync_openpgp_key_path',
+ 'sync_openpgp_key_refresh',
'sync_openpgp_key_refresh_retry_count',
'sync_openpgp_key_refresh_retry_delay_exp_base',
'sync_openpgp_key_refresh_retry_delay_max',
@@ -219,10 +214,10 @@ class RepoConfig(object):
self.sync_depth = repo_opts.get('sync-depth')
self.sync_hooks_only_on_change = repo_opts.get(
- 'sync-hooks-only-on-change', 'false').lower() == 'true'
+ 'sync-hooks-only-on-change', 'false').lower() in ('true', 'yes')
self.strict_misc_digests = repo_opts.get(
- 'strict-misc-digests', 'true').lower() == 'true'
+ 'strict-misc-digests', 'true').lower() in ('true', 'yes')
self.sync_allow_hardlinks = repo_opts.get(
'sync-allow-hardlinks', 'true').lower() in ('true', 'yes')
@@ -233,6 +228,9 @@ class RepoConfig(object):
self.sync_openpgp_key_path = repo_opts.get(
'sync-openpgp-key-path', None)
+ self.sync_openpgp_key_refresh = repo_opts.get(
+ 'sync-openpgp-key-refresh', 'true').lower() in ('true', 'yes')
+
for k in ('sync_openpgp_key_refresh_retry_count',
'sync_openpgp_key_refresh_retry_delay_exp_base',
'sync_openpgp_key_refresh_retry_delay_max',
@@ -259,10 +257,10 @@ class RepoConfig(object):
self.module_specific_options = {}
# Not implemented.
- format = repo_opts.get('format')
- if format is not None:
- format = format.strip()
- self.format = format
+ repo_format = repo_opts.get('format')
+ if repo_format is not None:
+ repo_format = repo_format.strip()
+ self.format = repo_format
self.user_location = None
location = repo_opts.get('location')
@@ -497,6 +495,8 @@ class RepoConfig(object):
repo_msg.append(indent + "location: " + self.location)
if not self.strict_misc_digests:
repo_msg.append(indent + "strict-misc-digests: false")
+ if not self.sync_openpgp_key_refresh:
+ repo_msg.append(indent + "sync-openpgp-key-refresh: no")
if self.sync_type:
repo_msg.append(indent + "sync-type: " + self.sync_type)
if self.sync_umask:
@@ -529,14 +529,8 @@ class RepoConfig(object):
d[k] = getattr(self, k, None)
return "%s" % (d,)
- if sys.hexversion < 0x3000000:
-
- __unicode__ = __str__
- def __str__(self):
- return _unicode_encode(self.__unicode__())
-
-class RepoConfigLoader(object):
+class RepoConfigLoader:
"""Loads and store config of several repositories, loaded from PORTDIR_OVERLAY or repos.conf"""
@staticmethod
@@ -609,6 +603,7 @@ class RepoConfigLoader(object):
'sync_hooks_only_on_change',
'sync_openpgp_keyserver',
'sync_openpgp_key_path',
+ 'sync_openpgp_key_refresh',
'sync_openpgp_key_refresh_retry_count',
'sync_openpgp_key_refresh_retry_delay_exp_base',
'sync_openpgp_key_refresh_retry_delay_max',
@@ -664,7 +659,7 @@ class RepoConfigLoader(object):
recursive_paths = []
for p in paths:
- if isinstance(p, basestring):
+ if isinstance(p, str):
recursive_paths.extend(_recursive_file_list(p))
else:
recursive_paths.append(p)
@@ -973,8 +968,7 @@ class RepoConfigLoader(object):
main_repo = self.prepos['DEFAULT'].main_repo
if main_repo is not None and main_repo in self.prepos:
return self.prepos[main_repo].location
- else:
- return ''
+ return ''
def mainRepo(self):
"""Returns the main repo"""
@@ -1047,6 +1041,7 @@ class RepoConfigLoader(object):
bool_keys = (
"strict_misc_digests",
"sync_allow_hardlinks",
+ "sync_openpgp_key_refresh",
"sync_rcu",
)
str_or_int_keys = (
diff --git a/lib/portage/repository/storage/hardlink_rcu.py b/lib/portage/repository/storage/hardlink_rcu.py
index 80cdbb0d7..bb2c8496b 100644
--- a/lib/portage/repository/storage/hardlink_rcu.py
+++ b/lib/portage/repository/storage/hardlink_rcu.py
@@ -1,4 +1,4 @@
-# Copyright 2018 Gentoo Foundation
+# Copyright 2018-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import datetime
@@ -204,6 +204,17 @@ class HardlinkRcuRepoStorage(RepoStorageInterface):
except OSError:
pass
os.symlink('snapshots/{}'.format(new_id), new_symlink)
+
+ # If SyncManager.pre_sync creates an empty directory where
+ # self._latest_symlink is suppose to be (which is normal if
+ # sync-rcu-store-dir has been removed), then we need to remove
+ # the directory or else rename will raise IsADirectoryError
+ # when we try to replace the directory with a symlink.
+ try:
+ os.rmdir(self._latest_symlink)
+ except OSError:
+ pass
+
os.rename(new_symlink, self._latest_symlink)
try:
diff --git a/lib/portage/repository/storage/interface.py b/lib/portage/repository/storage/interface.py
index f83c42b84..ce8a2a170 100644
--- a/lib/portage/repository/storage/interface.py
+++ b/lib/portage/repository/storage/interface.py
@@ -11,7 +11,7 @@ class RepoStorageException(PortageException):
"""
-class RepoStorageInterface(object):
+class RepoStorageInterface:
"""
Abstract repository storage interface.
diff --git a/lib/portage/sync/config_checks.py b/lib/portage/sync/config_checks.py
index db316aa88..3157d6130 100644
--- a/lib/portage/sync/config_checks.py
+++ b/lib/portage/sync/config_checks.py
@@ -34,7 +34,7 @@ def check_type(repo, logger, module_names):
return True
-class CheckSyncConfig(object):
+class CheckSyncConfig:
'''Base repos.conf settings checks class'''
def __init__(self, repo=None, logger=None):
diff --git a/lib/portage/sync/controller.py b/lib/portage/sync/controller.py
index c4c72e73a..6b47ae953 100644
--- a/lib/portage/sync/controller.py
+++ b/lib/portage/sync/controller.py
@@ -1,4 +1,4 @@
-# Copyright 2014-2019 Gentoo Authors
+# Copyright 2014-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
from __future__ import print_function
@@ -29,7 +29,7 @@ from portage import util
from _emerge.CompositeTask import CompositeTask
-class TaskHandler(object):
+class TaskHandler:
"""Handles the running of the tasks it is given
"""
@@ -82,7 +82,7 @@ def print_results(results):
print("\n")
-class SyncManager(object):
+class SyncManager:
'''Main sync control module'''
def __init__(self, settings, logger):
@@ -115,8 +115,7 @@ class SyncManager(object):
"has been renamed to sync_async",
DeprecationWarning, stacklevel=2)
return self.sync_async
- else:
- raise AttributeError(name)
+ raise AttributeError(name)
def get_module_descriptions(self, mod):
desc = self.module_controller.get_func_descriptions(mod)
@@ -231,7 +230,7 @@ class SyncManager(object):
# Redirect command stderr to stdout, in order to prevent
# spurious cron job emails (bug 566132).
spawn_kwargs["fd_pipes"] = {
- 0: sys.__stdin__.fileno(),
+ 0: portage._get_stdin().fileno(),
1: sys.__stdout__.fileno(),
2: sys.__stdout__.fileno()
}
@@ -396,4 +395,3 @@ class SyncRepo(CompositeTask):
self.returncode = sync_task.returncode
self.sync_callback(self.sync_task)
self._async_wait()
-
diff --git a/lib/portage/sync/getaddrinfo_validate.py b/lib/portage/sync/getaddrinfo_validate.py
index 5e6009c74..fd77f4875 100644
--- a/lib/portage/sync/getaddrinfo_validate.py
+++ b/lib/portage/sync/getaddrinfo_validate.py
@@ -1,10 +1,7 @@
-# Copyright 2010 Gentoo Foundation
+# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-import sys
-if sys.hexversion >= 0x3000000:
- basestring = str
def getaddrinfo_validate(addrinfos):
"""
@@ -19,7 +16,7 @@ def getaddrinfo_validate(addrinfos):
continue
if len(addrinfo[4]) < 2:
continue
- if not isinstance(addrinfo[4][0], basestring):
+ if not isinstance(addrinfo[4][0], str):
continue
except TypeError:
continue
diff --git a/lib/portage/sync/modules/git/__init__.py b/lib/portage/sync/modules/git/__init__.py
index 270d97186..2081d0d25 100644
--- a/lib/portage/sync/modules/git/__init__.py
+++ b/lib/portage/sync/modules/git/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2014-2018 Gentoo Foundation
+# Copyright 2014-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
doc = """Git plug-in module for portage.
@@ -14,6 +14,7 @@ class CheckGitConfig(CheckSyncConfig):
def __init__(self, repo, logger):
CheckSyncConfig.__init__(self, repo, logger)
self.checks.append('check_depth')
+ self.checks.append('check_verify_commit_signature')
def check_depth(self):
for attr in ('clone_depth', 'sync_depth'):
@@ -33,6 +34,16 @@ class CheckGitConfig(CheckSyncConfig):
else:
setattr(self.repo, attr, d)
+ def check_verify_commit_signature(self):
+ v = self.repo.module_specific_options.get(
+ 'sync-git-verify-commit-signature', 'false').lower()
+
+ if v not in ('yes', 'no', 'true', 'false'):
+ writemsg_level("!!! %s\n" %
+ _("sync-git-verify-commit-signature not one of: %s")
+ % ('{yes, no, true, false}'),
+ level=self.logger.ERROR, noiselevel=-1)
+
module_spec = {
'name': 'git',
diff --git a/lib/portage/sync/modules/git/git.py b/lib/portage/sync/modules/git/git.py
index 7df4b6d61..d87f1a601 100644
--- a/lib/portage/sync/modules/git/git.py
+++ b/lib/portage/sync/modules/git/git.py
@@ -1,4 +1,4 @@
-# Copyright 2005-2018 Gentoo Foundation
+# Copyright 2005-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import io
@@ -204,7 +204,7 @@ class GitSync(NewBase):
def verify_head(self, revision='-1'):
if (self.repo.module_specific_options.get(
- 'sync-git-verify-commit-signature', 'false') != 'true'):
+ 'sync-git-verify-commit-signature', 'false').lower() not in ('true', 'yes')):
return True
if self.repo.sync_openpgp_key_path is not None:
@@ -247,26 +247,25 @@ class GitSync(NewBase):
if status == 'G': # good signature is good
out.einfo('Trusted signature found on top commit')
return True
- elif status == 'U': # untrusted
+ if status == 'U': # untrusted
out.ewarn('Top commit signature is valid but not trusted')
return True
+ if status == 'B':
+ expl = 'bad signature'
+ elif status == 'X':
+ expl = 'expired signature'
+ elif status == 'Y':
+ expl = 'expired key'
+ elif status == 'R':
+ expl = 'revoked key'
+ elif status == 'E':
+ expl = 'unable to verify signature (missing key?)'
+ elif status == 'N':
+ expl = 'no signature'
else:
- if status == 'B':
- expl = 'bad signature'
- elif status == 'X':
- expl = 'expired signature'
- elif status == 'Y':
- expl = 'expired key'
- elif status == 'R':
- expl = 'revoked key'
- elif status == 'E':
- expl = 'unable to verify signature (missing key?)'
- elif status == 'N':
- expl = 'no signature'
- else:
- expl = 'unknown issue'
- out.eerror('No valid signature found: %s' % (expl,))
- return False
+ expl = 'unknown issue'
+ out.eerror('No valid signature found: %s' % (expl,))
+ return False
finally:
if openpgp_env is not None:
openpgp_env.close()
diff --git a/lib/portage/sync/modules/rsync/rsync.py b/lib/portage/sync/modules/rsync/rsync.py
index a40e1c854..33019534b 100644
--- a/lib/portage/sync/modules/rsync/rsync.py
+++ b/lib/portage/sync/modules/rsync/rsync.py
@@ -1,4 +1,4 @@
-# Copyright 1999-2018 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import sys
@@ -10,7 +10,6 @@ import datetime
import io
import re
import random
-import subprocess
import tempfile
import portage
@@ -36,11 +35,6 @@ try:
except ImportError:
gemato = None
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- _unicode = str
-else:
- _unicode = unicode
SERVER_OUT_OF_DATE = -1
EXCEEDED_MAX_RETRIES = -2
@@ -68,7 +62,7 @@ class RsyncSync(NewBase):
out = portage.output.EOutput(quiet=quiet)
syncuri = self.repo.sync_uri
if self.repo.module_specific_options.get(
- 'sync-rsync-vcs-ignore', 'false').lower() == 'true':
+ 'sync-rsync-vcs-ignore', 'false').lower() in ('true', 'yes'):
vcs_dirs = ()
else:
vcs_dirs = frozenset(VCS_DIRS)
@@ -102,7 +96,7 @@ class RsyncSync(NewBase):
# via default repos.conf though.
self.verify_metamanifest = (
self.repo.module_specific_options.get(
- 'sync-rsync-verify-metamanifest', 'no') in ('yes', 'true'))
+ 'sync-rsync-verify-metamanifest', 'no').lower() in ('yes', 'true'))
# Support overriding job count.
self.verify_jobs = self.repo.module_specific_options.get(
'sync-rsync-verify-jobs', None)
@@ -243,7 +237,7 @@ class RsyncSync(NewBase):
except socket.error as e:
writemsg_level(
"!!! getaddrinfo failed for '%s': %s\n"
- % (_unicode_decode(hostname), _unicode(e)),
+ % (_unicode_decode(hostname), str(e)),
noiselevel=-1, level=logging.ERROR)
if addrinfos:
diff --git a/lib/portage/sync/modules/webrsync/webrsync.py b/lib/portage/sync/modules/webrsync/webrsync.py
index 70f65cfcd..20cc25a2c 100644
--- a/lib/portage/sync/modules/webrsync/webrsync.py
+++ b/lib/portage/sync/modules/webrsync/webrsync.py
@@ -134,4 +134,3 @@ class PyWebRsync(SyncBase):
def sync(self, **kwargs):
'''Sync the repository'''
pass
-
diff --git a/lib/portage/sync/syncbase.py b/lib/portage/sync/syncbase.py
index 46644d68e..5f18e5ba3 100644
--- a/lib/portage/sync/syncbase.py
+++ b/lib/portage/sync/syncbase.py
@@ -1,4 +1,4 @@
-# Copyright 2014-2018 Gentoo Foundation
+# Copyright 2014-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
'''
@@ -6,7 +6,6 @@ Base class for performing sync operations.
This class contains common initialization code and functions.
'''
-from __future__ import unicode_literals
import functools
import logging
import os
@@ -21,7 +20,7 @@ from portage.util.futures.retry import retry
from portage.util.futures.executor.fork import ForkExecutor
from . import _SUBMODULE_PATH_MAP
-class SyncBase(object):
+class SyncBase:
'''Base Sync class for subclassing'''
short_desc = "Perform sync operations on repositories"
@@ -252,6 +251,13 @@ class SyncBase(object):
@type openpgp_env: gemato.openpgp.OpenPGPEnvironment
"""
out = portage.output.EOutput(quiet=('--quiet' in self.options['emerge_config'].opts))
+
+ if not self.repo.sync_openpgp_key_refresh:
+ out.ewarn('Key refresh is disabled via a repos.conf sync-openpgp-key-refresh')
+ out.ewarn('setting, and this is a security vulnerability because it prevents')
+ out.ewarn('detection of revoked keys!')
+ return
+
out.ebegin('Refreshing keys via WKD')
if openpgp_env.refresh_keys_wkd():
out.eend(0)
diff --git a/lib/portage/tests/bin/setup_env.py b/lib/portage/tests/bin/setup_env.py
index 33b167989..83d99528e 100644
--- a/lib/portage/tests/bin/setup_env.py
+++ b/lib/portage/tests/bin/setup_env.py
@@ -4,6 +4,7 @@
import tempfile
+import portage
from portage import os
from portage import shutil
from portage.const import PORTAGE_BIN_PATH
@@ -36,6 +37,7 @@ def binTestsInit():
env['PATH'] = bindir + ':' + os.environ['PATH']
env['PORTAGE_BIN_PATH'] = bindir
env['PORTAGE_PYM_PATH'] = PORTAGE_PYM_PATH
+ env['PORTAGE_PYTHON'] = portage._python_interpreter
env['PORTAGE_INST_UID'] = str(os.getuid())
env['PORTAGE_INST_GID'] = str(os.getgid())
env['DESTTREE'] = '/usr'
@@ -71,17 +73,17 @@ def portage_func(func, args, exit_status=0):
fd_pipes=fd_pipes, pre_exec=pre_exec)
f.close()
-def create_portage_wrapper(bin):
+def create_portage_wrapper(f):
def derived_func(*args):
newargs = list(args)
- newargs.insert(0, bin)
+ newargs.insert(0, f)
return portage_func(*newargs)
return derived_func
-for bin in os.listdir(os.path.join(bindir, 'ebuild-helpers')):
- if bin.startswith('do') or \
- bin.startswith('new') or \
- bin.startswith('prep') or \
- bin in ('fowners', 'fperms'):
- globals()[bin] = create_portage_wrapper(
- os.path.join(bindir, 'ebuild-helpers', bin))
+for f in os.listdir(os.path.join(bindir, 'ebuild-helpers')):
+ if (f.startswith('do') or
+ f.startswith('new') or
+ f.startswith('prep') or
+ f in ('fowners', 'fperms')):
+ globals()[f] = create_portage_wrapper(
+ os.path.join(bindir, 'ebuild-helpers', f))
diff --git a/lib/portage/tests/dbapi/test_auxdb.py b/lib/portage/tests/dbapi/test_auxdb.py
index 85d64c15e..5c79357d7 100644
--- a/lib/portage/tests/dbapi/test_auxdb.py
+++ b/lib/portage/tests/dbapi/test_auxdb.py
@@ -1,8 +1,6 @@
# Copyright 2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
from portage.tests import TestCase
from portage.tests.resolver.ResolverPlayground import ResolverPlayground
from portage.util.futures import asyncio
diff --git a/lib/portage/tests/dep/testAtom.py b/lib/portage/tests/dep/testAtom.py
index 4ee06e0a2..b454782d1 100644
--- a/lib/portage/tests/dep/testAtom.py
+++ b/lib/portage/tests/dep/testAtom.py
@@ -257,7 +257,7 @@ class TestAtom(TestCase):
("dev-libs/A[a,b=,!c=,d?,!e?,-f]", [], ["a", "b", "c", "d", "e", "f"], None),
)
- class use_flag_validator(object):
+ class use_flag_validator:
def __init__(self, iuse):
self.iuse = iuse
diff --git a/lib/portage/tests/dep/test_isvalidatom.py b/lib/portage/tests/dep/test_isvalidatom.py
index 9d3367aab..58d999646 100644
--- a/lib/portage/tests/dep/test_isvalidatom.py
+++ b/lib/portage/tests/dep/test_isvalidatom.py
@@ -4,7 +4,7 @@
from portage.tests import TestCase
from portage.dep import isvalidatom
-class IsValidAtomTestCase(object):
+class IsValidAtomTestCase:
def __init__(self, atom, expected, allow_wildcard=False,
allow_repo=False, allow_build_id=False):
self.atom = atom
diff --git a/lib/portage/tests/dep/test_match_from_list.py b/lib/portage/tests/dep/test_match_from_list.py
index 3080479c2..35ba3a445 100644
--- a/lib/portage/tests/dep/test_match_from_list.py
+++ b/lib/portage/tests/dep/test_match_from_list.py
@@ -1,16 +1,12 @@
-# Copyright 2006-2014 Gentoo Foundation
+# Copyright 2006-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-import sys
from portage.tests import TestCase
from portage.dep import Atom, match_from_list, _repo_separator
from portage.versions import catpkgsplit, _pkg_str
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
-class Package(object):
+class Package:
"""
Provides a minimal subset of attributes of _emerge.Package.Package
"""
@@ -34,16 +30,16 @@ class Package(object):
self.use = self._use_class([])
self.iuse = self._iuse_class([])
- class _use_class(object):
+ class _use_class:
def __init__(self, use):
self.enabled = frozenset(use)
- class _iuse_class(object):
+ class _iuse_class:
def __init__(self, iuse):
self.all = frozenset(iuse)
def is_valid_flag(self, flags):
- if isinstance(flags, basestring):
+ if isinstance(flags, str):
flags = [flags]
for flag in flags:
if not flag in self.all:
diff --git a/lib/portage/tests/dep/test_soname_atom_pickle.py b/lib/portage/tests/dep/test_soname_atom_pickle.py
index c3f339e2d..03a4893d1 100644
--- a/lib/portage/tests/dep/test_soname_atom_pickle.py
+++ b/lib/portage/tests/dep/test_soname_atom_pickle.py
@@ -1,9 +1,6 @@
# Copyright 2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
-import sys
from portage.dep.soname.SonameAtom import SonameAtom
from portage.tests import TestCase
diff --git a/lib/portage/tests/dep/test_use_reduce.py b/lib/portage/tests/dep/test_use_reduce.py
index d9ee5a309..316f28952 100644
--- a/lib/portage/tests/dep/test_use_reduce.py
+++ b/lib/portage/tests/dep/test_use_reduce.py
@@ -5,7 +5,7 @@ from portage.tests import TestCase
from portage.exception import InvalidDependString
from portage.dep import Atom, use_reduce
-class UseReduceTestCase(object):
+class UseReduceTestCase:
def __init__(self, deparray, uselist=[], masklist=[],
matchall=0, excludeall=[], is_src_uri=False,
eapi='0', opconvert=False, flat=False, expected_result=None,
diff --git a/lib/portage/tests/ebuild/test_config.py b/lib/portage/tests/ebuild/test_config.py
index dcb5ffe0d..60f3ecab4 100644
--- a/lib/portage/tests/ebuild/test_config.py
+++ b/lib/portage/tests/ebuild/test_config.py
@@ -1,8 +1,6 @@
# Copyright 2010-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import io
import tempfile
diff --git a/lib/portage/tests/ebuild/test_fetch.py b/lib/portage/tests/ebuild/test_fetch.py
index 9a8a4a544..5b67dc519 100644
--- a/lib/portage/tests/ebuild/test_fetch.py
+++ b/lib/portage/tests/ebuild/test_fetch.py
@@ -1,8 +1,6 @@
-# Copyright 2019 Gentoo Authors
+# Copyright 2019-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import functools
import io
import tempfile
@@ -169,7 +167,7 @@ class EbuildFetchTestCase(TestCase):
'--repositories-configuration', settings.repositories.config_string(),
'--repo', 'test_repo', '--mirror')
- env = os.environ.copy()
+ env = settings.environ()
env['PYTHONPATH'] = ':'.join(
filter(None, [PORTAGE_PYM_PATH] + os.environ.get('PYTHONPATH', '').split(':')))
diff --git a/lib/portage/tests/ebuild/test_spawn.py b/lib/portage/tests/ebuild/test_spawn.py
index a38e10972..2e2b47eb9 100644
--- a/lib/portage/tests/ebuild/test_spawn.py
+++ b/lib/portage/tests/ebuild/test_spawn.py
@@ -3,7 +3,6 @@
import errno
import io
-import sys
import tempfile
import portage
from portage import os
diff --git a/lib/portage/tests/ebuild/test_use_expand_incremental.py b/lib/portage/tests/ebuild/test_use_expand_incremental.py
index a58f08cb9..4e83e4f85 100644
--- a/lib/portage/tests/ebuild/test_use_expand_incremental.py
+++ b/lib/portage/tests/ebuild/test_use_expand_incremental.py
@@ -1,8 +1,6 @@
# Copyright 2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import io
from portage import os, _encodings
diff --git a/lib/portage/tests/emerge/test_config_protect.py b/lib/portage/tests/emerge/test_config_protect.py
index 06ab059ee..f88cb3b7b 100644
--- a/lib/portage/tests/emerge/test_config_protect.py
+++ b/lib/portage/tests/emerge/test_config_protect.py
@@ -1,8 +1,6 @@
# Copyright 2014-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import io
from functools import partial
import shutil
diff --git a/lib/portage/tests/env/__init__.py b/lib/portage/tests/env/__init__.py
index cbeabe5c6..59a3a1e22 100644
--- a/lib/portage/tests/env/__init__.py
+++ b/lib/portage/tests/env/__init__.py
@@ -1,4 +1,3 @@
# tests/portage/env/__init__.py -- Portage Unit Test functionality
# Copyright 2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-
diff --git a/lib/portage/tests/env/config/__init__.py b/lib/portage/tests/env/config/__init__.py
index ef5cc43b6..daa503ba3 100644
--- a/lib/portage/tests/env/config/__init__.py
+++ b/lib/portage/tests/env/config/__init__.py
@@ -1,4 +1,3 @@
# tests/portage/env/config/__init__.py -- Portage Unit Test functionality
# Copyright 2007 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-
diff --git a/lib/portage/tests/glsa/test_security_set.py b/lib/portage/tests/glsa/test_security_set.py
index a602f83d4..025fcd864 100644
--- a/lib/portage/tests/glsa/test_security_set.py
+++ b/lib/portage/tests/glsa/test_security_set.py
@@ -1,8 +1,6 @@
# Copyright 2013-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import io
import portage
diff --git a/lib/portage/tests/lint/test_bash_syntax.py b/lib/portage/tests/lint/test_bash_syntax.py
index fdbb6fe88..da6ee4f45 100644
--- a/lib/portage/tests/lint/test_bash_syntax.py
+++ b/lib/portage/tests/lint/test_bash_syntax.py
@@ -4,7 +4,6 @@
from itertools import chain
import stat
import subprocess
-import sys
from portage.const import BASH_BINARY, PORTAGE_BASE_PATH, PORTAGE_BIN_PATH
from portage.tests import TestCase
diff --git a/lib/portage/tests/process/test_AsyncFunction.py b/lib/portage/tests/process/test_AsyncFunction.py
new file mode 100644
index 000000000..55857026d
--- /dev/null
+++ b/lib/portage/tests/process/test_AsyncFunction.py
@@ -0,0 +1,38 @@
+# Copyright 2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+import sys
+
+from portage import os
+from portage.tests import TestCase
+from portage.util._async.AsyncFunction import AsyncFunction
+from portage.util.futures import asyncio
+from portage.util.futures._asyncio.streams import _writer
+from portage.util.futures.compat_coroutine import coroutine
+from portage.util.futures.unix_events import _set_nonblocking
+
+
+class AsyncFunctionTestCase(TestCase):
+
+ @staticmethod
+ def _read_from_stdin(pw):
+ os.close(pw)
+ return ''.join(sys.stdin)
+
+ @coroutine
+ def _testAsyncFunctionStdin(self, loop):
+ test_string = '1\n2\n3\n'
+ pr, pw = os.pipe()
+ fd_pipes = {0:pr}
+ reader = AsyncFunction(scheduler=loop, fd_pipes=fd_pipes, target=self._read_from_stdin, args=(pw,))
+ reader.start()
+ os.close(pr)
+ _set_nonblocking(pw)
+ with open(pw, mode='wb', buffering=0) as pipe_write:
+ yield _writer(pipe_write, test_string.encode('utf_8'), loop=loop)
+ self.assertEqual((yield reader.async_wait()), os.EX_OK)
+ self.assertEqual(reader.result, test_string)
+
+ def testAsyncFunctionStdin(self):
+ loop = asyncio._wrap_loop()
+ loop.run_until_complete(self._testAsyncFunctionStdin(loop))
diff --git a/lib/portage/tests/process/test_PipeLogger.py b/lib/portage/tests/process/test_PipeLogger.py
new file mode 100644
index 000000000..2bd94cf39
--- /dev/null
+++ b/lib/portage/tests/process/test_PipeLogger.py
@@ -0,0 +1,58 @@
+# Copyright 2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+from portage import os
+from portage.tests import TestCase
+from portage.util._async.PipeLogger import PipeLogger
+from portage.util.futures import asyncio
+from portage.util.futures._asyncio.streams import _reader, _writer
+from portage.util.futures.compat_coroutine import coroutine, coroutine_return
+from portage.util.futures.unix_events import _set_nonblocking
+
+
+class PipeLoggerTestCase(TestCase):
+
+ @coroutine
+ def _testPipeLoggerToPipe(self, test_string, loop=None):
+ """
+ Test PipeLogger writing to a pipe connected to a PipeReader.
+ This verifies that PipeLogger does not deadlock when writing
+ to a pipe that's drained by a PipeReader running in the same
+ process (requires non-blocking write).
+ """
+
+ input_fd, writer_pipe = os.pipe()
+ _set_nonblocking(writer_pipe)
+ writer_pipe = os.fdopen(writer_pipe, 'wb', 0)
+ writer = asyncio.ensure_future(_writer(writer_pipe, test_string.encode('ascii'), loop=loop), loop=loop)
+ writer.add_done_callback(lambda writer: writer_pipe.close())
+
+ pr, pw = os.pipe()
+
+ consumer = PipeLogger(background=True,
+ input_fd=input_fd,
+ log_file_path=os.fdopen(pw, 'wb', 0),
+ scheduler=loop)
+ consumer.start()
+
+ # Before starting the reader, wait here for a moment, in order
+ # to exercise PipeLogger's handling of EAGAIN during write.
+ yield asyncio.wait([writer], timeout=0.01)
+
+ reader = _reader(pr, loop=loop)
+ yield writer
+ content = yield reader
+ yield consumer.async_wait()
+
+ self.assertEqual(consumer.returncode, os.EX_OK)
+
+ coroutine_return(content.decode('ascii', 'replace'))
+
+ def testPipeLogger(self):
+ loop = asyncio._wrap_loop()
+
+ for x in (1, 2, 5, 6, 7, 8, 2**5, 2**10, 2**12, 2**13, 2**14, 2**17, 2**17 + 1):
+ test_string = x * "a"
+ output = loop.run_until_complete(self._testPipeLoggerToPipe(test_string, loop=loop))
+ self.assertEqual(test_string, output,
+ "x = %s, len(output) = %s" % (x, len(output)))
diff --git a/lib/portage/tests/process/test_poll.py b/lib/portage/tests/process/test_poll.py
index f505b5049..dc11f6d13 100644
--- a/lib/portage/tests/process/test_poll.py
+++ b/lib/portage/tests/process/test_poll.py
@@ -1,11 +1,10 @@
-# Copyright 1998-2019 Gentoo Authors
+# Copyright 1998-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import functools
import pty
import shutil
import socket
-import sys
import tempfile
from portage import os
@@ -34,11 +33,8 @@ class PipeReaderTestCase(TestCase):
def test_domain_socket(self):
def make_pipes():
- if sys.version_info >= (3, 2):
- read_end, write_end = socket.socketpair()
- return (read_end.detach(), write_end.detach()), None
- else:
- self.skipTest('socket detach not supported')
+ read_end, write_end = socket.socketpair()
+ return (read_end.detach(), write_end.detach()), None
self._do_test(make_pipes)
def test_named_pipe(self):
diff --git a/lib/portage/tests/resolver/ResolverPlayground.py b/lib/portage/tests/resolver/ResolverPlayground.py
index 0751e392e..8996eba92 100644
--- a/lib/portage/tests/resolver/ResolverPlayground.py
+++ b/lib/portage/tests/resolver/ResolverPlayground.py
@@ -4,7 +4,6 @@
import bz2
from itertools import permutations
import fnmatch
-import sys
import tempfile
import portage
from portage import os
@@ -34,11 +33,8 @@ try:
except ImportError:
cnf_path_repoman = None
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
-class ResolverPlayground(object):
+class ResolverPlayground:
"""
This class helps to create the necessary files on disk and
the needed settings instances, etc. for the resolver to do
@@ -91,6 +87,7 @@ class ResolverPlayground(object):
"chgrp",
"chmod",
"chown",
+ "comm",
"cp",
"egrep",
"env",
@@ -411,7 +408,7 @@ class ResolverPlayground(object):
for eclass_name, eclass_content in eclasses.items():
with open(os.path.join(eclass_dir, "{}.eclass".format(eclass_name)), 'wt') as f:
- if isinstance(eclass_content, basestring):
+ if isinstance(eclass_content, str):
eclass_content = [eclass_content]
for line in eclass_content:
f.write("{}\n".format(line))
@@ -644,7 +641,7 @@ class ResolverPlayground(object):
else:
shutil.rmtree(self.eroot)
-class ResolverPlaygroundTestCase(object):
+class ResolverPlaygroundTestCase:
def __init__(self, request, **kwargs):
self.all_permutations = kwargs.pop("all_permutations", False)
@@ -695,7 +692,7 @@ class ResolverPlaygroundTestCase(object):
if expected:
new_expected = []
for obj in expected:
- if isinstance(obj, basestring):
+ if isinstance(obj, str):
if obj[:1] == "!":
new_expected.append(obj)
continue
@@ -720,7 +717,7 @@ class ResolverPlaygroundTestCase(object):
while got_stack and expected_stack:
got_token = got_stack.pop()
expected_obj = expected_stack.pop()
- if isinstance(expected_obj, basestring):
+ if isinstance(expected_obj, str):
new_expected.append(expected_obj)
if got_token == expected_obj:
continue
@@ -822,7 +819,7 @@ def _mergelist_str(x, depgraph):
return mergelist_str
-class ResolverPlaygroundResult(object):
+class ResolverPlaygroundResult:
checks = (
"success", "mergelist", "use_changes", "license_changes",
@@ -916,7 +913,7 @@ class ResolverPlaygroundResult(object):
if required_use_unsatisfied:
self.required_use_unsatisfied = set(required_use_unsatisfied)
-class ResolverPlaygroundDepcleanResult(object):
+class ResolverPlaygroundDepcleanResult:
checks = (
"success", "cleanlist", "ordered", "req_pkg_count",
diff --git a/lib/portage/tests/resolver/test_binary_pkg_ebuild_visibility.py b/lib/portage/tests/resolver/test_binary_pkg_ebuild_visibility.py
index 0d01d0696..0cd650402 100644
--- a/lib/portage/tests/resolver/test_binary_pkg_ebuild_visibility.py
+++ b/lib/portage/tests/resolver/test_binary_pkg_ebuild_visibility.py
@@ -141,4 +141,3 @@ class BinaryPkgEbuildVisibilityTestCase(TestCase):
test_case.fail_msg)
finally:
playground.cleanup()
-
diff --git a/lib/portage/tests/resolver/test_profile_default_eapi.py b/lib/portage/tests/resolver/test_profile_default_eapi.py
index cc5721949..130c231fd 100644
--- a/lib/portage/tests/resolver/test_profile_default_eapi.py
+++ b/lib/portage/tests/resolver/test_profile_default_eapi.py
@@ -1,8 +1,6 @@
# Copyright 2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import io
from portage import os, _encodings
diff --git a/lib/portage/tests/resolver/test_profile_package_set.py b/lib/portage/tests/resolver/test_profile_package_set.py
index 88a2a8259..a11609832 100644
--- a/lib/portage/tests/resolver/test_profile_package_set.py
+++ b/lib/portage/tests/resolver/test_profile_package_set.py
@@ -1,8 +1,6 @@
# Copyright 2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import io
from portage import os, _encodings
diff --git a/lib/portage/tests/sets/files/testConfigFileSet.py b/lib/portage/tests/sets/files/testConfigFileSet.py
index 3ec26a077..395da062a 100644
--- a/lib/portage/tests/sets/files/testConfigFileSet.py
+++ b/lib/portage/tests/sets/files/testConfigFileSet.py
@@ -29,4 +29,3 @@ class ConfigFileSetTestCase(TestCase):
s = ConfigFileSet(self.testfile)
s.load()
self.assertEqual(set(test_cps), s.getAtoms())
-
diff --git a/lib/portage/tests/sets/files/testStaticFileSet.py b/lib/portage/tests/sets/files/testStaticFileSet.py
index d515a6728..11fc9a9d8 100644
--- a/lib/portage/tests/sets/files/testStaticFileSet.py
+++ b/lib/portage/tests/sets/files/testStaticFileSet.py
@@ -24,4 +24,3 @@ class StaticFileSetTestCase(TestCase):
s = StaticFileSet(self.testfile)
s.load()
self.assertEqual(set(test_cps), s.getAtoms())
-
diff --git a/lib/portage/tests/sets/shell/testShell.py b/lib/portage/tests/sets/shell/testShell.py
index 2cdd833c3..58dc750bf 100644
--- a/lib/portage/tests/sets/shell/testShell.py
+++ b/lib/portage/tests/sets/shell/testShell.py
@@ -17,12 +17,12 @@ class CommandOutputSetTestCase(TestCase):
def testCommand(self):
- input = set(test_cps)
+ params = set(test_cps)
command = find_binary("bash")
command += " -c '"
- for a in input:
- command += " echo -e \"%s\" ; " % a
+ for a in params:
+ command += " echo -e \"%s\" ; " % a
command += "'"
s = CommandOutputSet(command)
atoms = s.getAtoms()
- self.assertEqual(atoms, input)
+ self.assertEqual(atoms, params)
diff --git a/lib/portage/tests/sync/test_sync_local.py b/lib/portage/tests/sync/test_sync_local.py
index 5fb8afb7c..efd61aac8 100644
--- a/lib/portage/tests/sync/test_sync_local.py
+++ b/lib/portage/tests/sync/test_sync_local.py
@@ -1,11 +1,10 @@
-# Copyright 2014-2015 Gentoo Foundation
+# Copyright 2014-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import datetime
import subprocess
import sys
import textwrap
-import time
import portage
from portage import os, shutil, _shell_quote
@@ -72,6 +71,7 @@ class SyncLocalTestCase(TestCase):
distdir = os.path.join(eprefix, "distdir")
repo = settings.repositories["test_repo"]
metadata_dir = os.path.join(repo.location, "metadata")
+ rcu_store_dir = os.path.join(eprefix, 'var/repositories/test_repo_rcu_storedir')
cmds = {}
for cmd in ("emerge", "emaint"):
@@ -192,6 +192,10 @@ class SyncLocalTestCase(TestCase):
(homedir, lambda: os.mkdir(repo.user_location)),
)
+ delete_rcu_store_dir = (
+ (homedir, lambda: shutil.rmtree(rcu_store_dir)),
+ )
+
revert_rcu_layout = (
(homedir, lambda: os.rename(repo.user_location, repo.user_location + '.bak')),
(homedir, lambda: os.rename(os.path.realpath(repo.user_location + '.bak'), repo.user_location)),
@@ -290,7 +294,8 @@ class SyncLocalTestCase(TestCase):
for cwd, cmd in rename_repo + sync_cmds_auto_sync + sync_cmds + \
rsync_opts_repos + rsync_opts_repos_default + \
rsync_opts_repos_default_ovr + rsync_opts_repos_default_cancel + \
- bump_timestamp_cmds + sync_rsync_rcu + sync_cmds + revert_rcu_layout + \
+ bump_timestamp_cmds + sync_rsync_rcu + sync_cmds + delete_rcu_store_dir + \
+ sync_cmds + revert_rcu_layout + \
delete_repo_location + sync_cmds + sync_cmds + \
bump_timestamp_cmds + sync_cmds + revert_rcu_layout + \
delete_sync_repo + git_repo_create + sync_type_git + \
diff --git a/lib/portage/tests/unicode/test_string_format.py b/lib/portage/tests/unicode/test_string_format.py
index 9d4366a91..3b994d622 100644
--- a/lib/portage/tests/unicode/test_string_format.py
+++ b/lib/portage/tests/unicode/test_string_format.py
@@ -1,9 +1,6 @@
-# Copyright 2010-2014 Gentoo Foundation
+# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
-import sys
from portage import _encodings, _unicode_encode
from portage.exception import PortageException
@@ -11,11 +8,6 @@ from portage.tests import TestCase
from _emerge.DependencyArg import DependencyArg
from _emerge.UseFlagDisplay import UseFlagDisplay
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
-
-STR_IS_UNICODE = sys.hexversion >= 0x3000000
class StringFormatTestCase(TestCase):
"""
@@ -44,17 +36,9 @@ class StringFormatTestCase(TestCase):
formatted_str = "%s" % (dependency_arg,)
self.assertEqual(formatted_str, arg_unicode)
- if STR_IS_UNICODE:
-
- # Test the __str__ method which returns unicode in python3
- formatted_str = "%s" % (dependency_arg,)
- self.assertEqual(formatted_str, arg_unicode)
-
- else:
-
- # Test the __str__ method which returns encoded bytes in python2
- formatted_bytes = b"%s" % (dependency_arg,)
- self.assertEqual(formatted_bytes, arg_bytes)
+ # Test the __str__ method which returns unicode in python3
+ formatted_str = "%s" % (dependency_arg,)
+ self.assertEqual(formatted_str, arg_unicode)
def testPortageException(self):
@@ -69,17 +53,9 @@ class StringFormatTestCase(TestCase):
formatted_str = "%s" % (e,)
self.assertEqual(formatted_str, arg_unicode)
- if STR_IS_UNICODE:
-
- # Test the __str__ method which returns unicode in python3
- formatted_str = "%s" % (e,)
- self.assertEqual(formatted_str, arg_unicode)
-
- else:
-
- # Test the __str__ method which returns encoded bytes in python2
- formatted_bytes = b"%s" % (e,)
- self.assertEqual(formatted_bytes, arg_bytes)
+ # Test the __str__ method which returns unicode in python3
+ formatted_str = "%s" % (e,)
+ self.assertEqual(formatted_str, arg_unicode)
def testUseFlagDisplay(self):
@@ -93,16 +69,8 @@ class StringFormatTestCase(TestCase):
# Use unicode_literals for unicode format string so that
# __unicode__() is called in Python 2.
formatted_str = "%s" % (e,)
- self.assertEqual(isinstance(formatted_str, basestring), True)
+ self.assertEqual(isinstance(formatted_str, str), True)
- if STR_IS_UNICODE:
-
- # Test the __str__ method which returns unicode in python3
- formatted_str = "%s" % (e,)
- self.assertEqual(isinstance(formatted_str, str), True)
-
- else:
-
- # Test the __str__ method which returns encoded bytes in python2
- formatted_bytes = b"%s" % (e,)
- self.assertEqual(isinstance(formatted_bytes, bytes), True)
+ # Test the __str__ method which returns unicode in python3
+ formatted_str = "%s" % (e,)
+ self.assertEqual(isinstance(formatted_str, str), True)
diff --git a/lib/portage/tests/util/__init__.py b/lib/portage/tests/util/__init__.py
index 69ce1898d..858d731e4 100644
--- a/lib/portage/tests/util/__init__.py
+++ b/lib/portage/tests/util/__init__.py
@@ -1,4 +1,3 @@
# tests/portage.util/__init__.py -- Portage Unit Test functionality
# Copyright 2006 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-
diff --git a/lib/portage/tests/util/futures/asyncio/test_pipe_closed.py b/lib/portage/tests/util/futures/asyncio/test_pipe_closed.py
index 507385c04..d9ada8b70 100644
--- a/lib/portage/tests/util/futures/asyncio/test_pipe_closed.py
+++ b/lib/portage/tests/util/futures/asyncio/test_pipe_closed.py
@@ -1,4 +1,4 @@
-# Copyright 2018 Gentoo Foundation
+# Copyright 2018-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import errno
@@ -6,7 +6,6 @@ import os
import pty
import shutil
import socket
-import sys
import tempfile
from portage.tests import TestCase
@@ -18,7 +17,7 @@ from portage.util.futures.unix_events import (
)
-class _PipeClosedTestCase(object):
+class _PipeClosedTestCase:
def test_pipe(self):
read_end, write_end = os.pipe()
@@ -32,10 +31,7 @@ class _PipeClosedTestCase(object):
self._do_test(read_end, write_end)
def test_domain_socket(self):
- if sys.version_info >= (3, 2):
- read_end, write_end = socket.socketpair()
- else:
- self.skipTest('socket detach not supported')
+ read_end, write_end = socket.socketpair()
self._do_test(read_end.detach(), write_end.detach())
def test_named_pipe(self):
diff --git a/lib/portage/tests/util/futures/asyncio/test_policy_wrapper_recursion.py b/lib/portage/tests/util/futures/asyncio/test_policy_wrapper_recursion.py
index d3cd94b35..900bb5115 100644
--- a/lib/portage/tests/util/futures/asyncio/test_policy_wrapper_recursion.py
+++ b/lib/portage/tests/util/futures/asyncio/test_policy_wrapper_recursion.py
@@ -1,10 +1,7 @@
# Copyright 2018 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-try:
- import asyncio
-except ImportError:
- asyncio = None
+import asyncio
from portage.tests import TestCase
from portage.util.futures.unix_events import DefaultEventLoopPolicy
@@ -12,9 +9,6 @@ from portage.util.futures.unix_events import DefaultEventLoopPolicy
class PolicyWrapperRecursionTestCase(TestCase):
def testPolicyWrapperRecursion(self):
- if asyncio is None:
- self.skipTest('asyncio is not available')
-
initial_policy = asyncio.get_event_loop_policy()
if not isinstance(initial_policy, DefaultEventLoopPolicy):
asyncio.set_event_loop_policy(DefaultEventLoopPolicy())
diff --git a/lib/portage/tests/util/futures/asyncio/test_subprocess_exec.py b/lib/portage/tests/util/futures/asyncio/test_subprocess_exec.py
index d7e94d132..6128a7d06 100644
--- a/lib/portage/tests/util/futures/asyncio/test_subprocess_exec.py
+++ b/lib/portage/tests/util/futures/asyncio/test_subprocess_exec.py
@@ -3,7 +3,6 @@
import os
import subprocess
-import sys
from portage.process import find_binary
from portage.tests import TestCase
@@ -132,8 +131,6 @@ class SubprocessExecTestCase(TestCase):
requires an AbstractEventLoop.connect_read_pipe implementation
(and a ReadTransport implementation for it to return).
"""
- if sys.version_info.major < 3:
- self.skipTest('ReadTransport not implemented for python2')
args_tuple = (b'hello', b'world')
echo_binary = find_binary("echo")
@@ -162,8 +159,6 @@ class SubprocessExecTestCase(TestCase):
requires an AbstractEventLoop.connect_write_pipe implementation
(and a WriteTransport implementation for it to return).
"""
- if sys.version_info.major < 3:
- self.skipTest('WriteTransport not implemented for python2')
stdin_data = b'hello world'
cat_binary = find_binary("cat")
diff --git a/lib/portage/tests/util/futures/test_compat_coroutine.py b/lib/portage/tests/util/futures/test_compat_coroutine.py
index b561c0227..5a8230432 100644
--- a/lib/portage/tests/util/futures/test_compat_coroutine.py
+++ b/lib/portage/tests/util/futures/test_compat_coroutine.py
@@ -123,7 +123,7 @@ class CompatCoroutineTestCase(TestCase):
def test_method_coroutine(self):
- class Cubby(object):
+ class Cubby:
_empty = object()
diff --git a/lib/portage/tests/util/futures/test_retry.py b/lib/portage/tests/util/futures/test_retry.py
index 7a1e76280..ce5fb3e11 100644
--- a/lib/portage/tests/util/futures/test_retry.py
+++ b/lib/portage/tests/util/futures/test_retry.py
@@ -1,17 +1,14 @@
-# Copyright 2018 Gentoo Foundation
+# Copyright 2018-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-try:
- from concurrent.futures import ThreadPoolExecutor
-except ImportError:
- ThreadPoolExecutor = None
+from concurrent.futures import ThreadPoolExecutor
try:
import threading
except ImportError:
import dummy_threading as threading
-import sys
+import time
from portage.tests import TestCase
from portage.util._eventloop.global_event_loop import global_event_loop
@@ -19,24 +16,23 @@ from portage.util.backoff import RandomExponentialBackoff
from portage.util.futures import asyncio
from portage.util.futures.retry import retry
from portage.util.futures.executor.fork import ForkExecutor
-from portage.util.monotonic import monotonic
class SucceedLaterException(Exception):
pass
-class SucceedLater(object):
+class SucceedLater:
"""
A callable object that succeeds some duration of time has passed.
"""
def __init__(self, duration):
- self._succeed_time = monotonic() + duration
+ self._succeed_time = time.monotonic() + duration
def __call__(self):
loop = global_event_loop()
result = loop.create_future()
- remaining = self._succeed_time - monotonic()
+ remaining = self._succeed_time - time.monotonic()
if remaining > 0:
loop.call_soon_threadsafe(lambda: None if result.done() else
result.set_exception(SucceedLaterException(
@@ -51,7 +47,7 @@ class SucceedNeverException(Exception):
pass
-class SucceedNever(object):
+class SucceedNever:
"""
A callable object that never succeeds.
"""
@@ -63,7 +59,7 @@ class SucceedNever(object):
return result
-class HangForever(object):
+class HangForever:
"""
A callable object that sleeps forever.
"""
@@ -207,12 +203,12 @@ class RetryForkExecutorTestCase(RetryTestCase):
lambda kill_switch: event.set())
event.wait()
return result.result()
- else:
- # child process
- try:
- return loop.run_until_complete(coroutine_func())
- finally:
- loop.close()
+
+ # child process
+ try:
+ return loop.run_until_complete(coroutine_func())
+ finally:
+ loop.close()
def execute_wrapper():
kill_switch = parent_loop.create_future()
@@ -229,6 +225,4 @@ class RetryForkExecutorTestCase(RetryTestCase):
class RetryThreadExecutorTestCase(RetryForkExecutorTestCase):
def _setUpExecutor(self):
- if sys.version_info.major < 3:
- self.skipTest('ThreadPoolExecutor not supported for python2')
self._executor = ThreadPoolExecutor(max_workers=1)
diff --git a/lib/portage/tests/util/test_socks5.py b/lib/portage/tests/util/test_socks5.py
index 5db85b0a6..ca32651a7 100644
--- a/lib/portage/tests/util/test_socks5.py
+++ b/lib/portage/tests/util/test_socks5.py
@@ -2,11 +2,9 @@
# Distributed under the terms of the GNU General Public License v2
import functools
-import platform
import shutil
import socket
import struct
-import sys
import tempfile
import time
@@ -16,15 +14,8 @@ from portage.util._eventloop.global_event_loop import global_event_loop
from portage.util import socks5
from portage.const import PORTAGE_BIN_PATH
-try:
- from http.server import BaseHTTPRequestHandler, HTTPServer
-except ImportError:
- from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
-
-try:
- from urllib.request import urlopen
-except ImportError:
- from urllib import urlopen
+from http.server import BaseHTTPRequestHandler, HTTPServer
+from urllib.request import urlopen
class _Handler(BaseHTTPRequestHandler):
@@ -58,7 +49,7 @@ class _Handler(BaseHTTPRequestHandler):
pass
-class AsyncHTTPServer(object):
+class AsyncHTTPServer:
def __init__(self, host, content, loop):
self._host = host
self._content = content
@@ -193,19 +184,13 @@ class Socks5ServerTestCase(TestCase):
'PORTAGE_BIN_PATH': PORTAGE_BIN_PATH,
}
- try:
- proxy = socks5.get_socks5_proxy(settings)
- except NotImplementedError:
- # bug 658172 for python2.7
- self.skipTest('get_socks5_proxy not implemented for {} {}.{}'.format(
- platform.python_implementation(), *sys.version_info[:2]))
- else:
- loop.run_until_complete(socks5.proxy.ready())
+ proxy = socks5.get_socks5_proxy(settings)
+ loop.run_until_complete(socks5.proxy.ready())
- result = loop.run_until_complete(loop.run_in_executor(None,
- self._fetch_via_proxy, proxy, host, server.server_port, path))
+ result = loop.run_until_complete(loop.run_in_executor(None,
+ self._fetch_via_proxy, proxy, host, server.server_port, path))
- self.assertEqual(result, content)
+ self.assertEqual(result, content)
finally:
socks5.proxy.stop()
shutil.rmtree(tempdir)
diff --git a/lib/portage/tests/util/test_xattr.py b/lib/portage/tests/util/test_xattr.py
index 2e2564a6e..8e8c2a3d6 100644
--- a/lib/portage/tests/util/test_xattr.py
+++ b/lib/portage/tests/util/test_xattr.py
@@ -5,16 +5,7 @@
from __future__ import print_function
-try:
- # Try python-3.3 module first.
- # pylint: disable=no-name-in-module
- from unittest import mock
-except ImportError:
- try:
- # Try standalone module.
- import mock
- except ImportError:
- mock = None
+from unittest import mock
import subprocess
@@ -50,9 +41,6 @@ class SystemCommandsTest(TestCase):
))
def _setUp(self):
- if mock is None:
- self.skipTest('need mock for testing')
-
return _XattrSystemCommands
def _testGetBasic(self):
diff --git a/lib/portage/update.py b/lib/portage/update.py
index 1920d213a..07e977452 100644
--- a/lib/portage/update.py
+++ b/lib/portage/update.py
@@ -1,8 +1,6 @@
-# Copyright 1999-2014 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import errno
import io
import re
@@ -27,12 +25,6 @@ from portage.eapi import _get_eapi_attrs
from portage.exception import DirectoryNotFound, InvalidAtom, PortageException
from portage.localization import _
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- long = int
- _unicode = str
-else:
- _unicode = unicode
ignored_dbentries = ("CONTENTS", "environment.bz2")
@@ -42,8 +34,8 @@ def update_dbentry(update_cmd, mycontent, eapi=None, parent=None):
eapi = parent.eapi
if update_cmd[0] == "move":
- old_value = _unicode(update_cmd[1])
- new_value = _unicode(update_cmd[2])
+ old_value = str(update_cmd[1])
+ new_value = str(update_cmd[2])
# Use isvalidatom() to check if this move is valid for the
# EAPI (characters allowed in package names may vary).
@@ -70,7 +62,7 @@ def update_dbentry(update_cmd, mycontent, eapi=None, parent=None):
match_from_list(new_atom, [parent]):
continue
- split_content[i] = _unicode(new_atom)
+ split_content[i] = str(new_atom)
modified = True
if modified:
@@ -197,7 +189,7 @@ def grab_updates(updpath, prev_mtimes=None):
mystat = os.stat(file_path)
if update_data or \
file_path not in prev_mtimes or \
- long(prev_mtimes[file_path]) != mystat[stat.ST_MTIME]:
+ int(prev_mtimes[file_path]) != mystat[stat.ST_MTIME]:
f = io.open(_unicode_encode(file_path,
encoding=_encodings['fs'], errors='strict'),
mode='r', encoding=_encodings['repo.content'], errors='replace')
diff --git a/lib/portage/util/SlotObject.py b/lib/portage/util/SlotObject.py
index ba6215874..1f38a6cb8 100644
--- a/lib/portage/util/SlotObject.py
+++ b/lib/portage/util/SlotObject.py
@@ -1,7 +1,7 @@
# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-class SlotObject(object):
+class SlotObject:
__slots__ = ("__weakref__",)
def __init__(self, **kwargs):
diff --git a/lib/portage/util/_ShelveUnicodeWrapper.py b/lib/portage/util/_ShelveUnicodeWrapper.py
deleted file mode 100644
index adbd5199f..000000000
--- a/lib/portage/util/_ShelveUnicodeWrapper.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2013 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-class ShelveUnicodeWrapper(object):
- """
- Convert unicode to str and back again, since python-2.x shelve
- module doesn't support unicode.
- """
- def __init__(self, shelve_instance):
- self._shelve = shelve_instance
-
- def _encode(self, s):
- if isinstance(s, unicode):
- s = s.encode('utf_8')
- return s
-
- def __len__(self):
- return len(self._shelve)
-
- def __contains__(self, k):
- return self._encode(k) in self._shelve
-
- def __iter__(self):
- return self._shelve.__iter__()
-
- def items(self):
- return self._shelve.iteritems()
-
- def __setitem__(self, k, v):
- self._shelve[self._encode(k)] = self._encode(v)
-
- def __getitem__(self, k):
- return self._shelve[self._encode(k)]
-
- def __delitem__(self, k):
- del self._shelve[self._encode(k)]
-
- def get(self, k, *args):
- return self._shelve.get(self._encode(k), *args)
-
- def close(self):
- self._shelve.close()
-
- def clear(self):
- self._shelve.clear()
diff --git a/lib/portage/util/__init__.py b/lib/portage/util/__init__.py
index 6bff97fb7..322b217be 100644
--- a/lib/portage/util/__init__.py
+++ b/lib/portage/util/__init__.py
@@ -1,8 +1,6 @@
-# Copyright 2004-2017 Gentoo Foundation
+# Copyright 2004-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
__all__ = ['apply_permissions', 'apply_recursive_permissions',
'apply_secpass_permissions', 'apply_stat_permissions', 'atomic_ofstream',
'cmp_sort_key', 'ConfigProtect', 'dump_traceback', 'ensure_dirs',
@@ -16,10 +14,7 @@ __all__ = ['apply_permissions', 'apply_recursive_permissions',
from copy import deepcopy
import errno
import io
-try:
- from itertools import chain, filterfalse
-except ImportError:
- from itertools import chain, ifilterfalse as filterfalse
+from itertools import chain, filterfalse
import logging
import re
import shlex
@@ -50,10 +45,6 @@ from portage.proxy.objectproxy import ObjectProxy
from portage.cache.mappings import UserDict
from portage.const import EPREFIX
-if sys.hexversion >= 0x3000000:
- _unicode = str
-else:
- _unicode = unicode
noiselimit = 0
@@ -79,7 +70,7 @@ def writemsg(mystr, noiselevel=0, fd=None):
else:
mystr = _unicode_encode(mystr,
encoding=_encodings['stdio'], errors='backslashreplace')
- if sys.hexversion >= 0x3000000 and fd in (sys.stdout, sys.stderr):
+ if fd in (sys.stdout, sys.stderr):
fd = fd.buffer
fd.write(mystr)
fd.flush()
@@ -114,7 +105,7 @@ def normalize_path(mypath):
We dislike this behavior so we create our own normpath func
to fix it.
"""
- if sys.hexversion >= 0x3000000 and isinstance(mypath, bytes):
+ if isinstance(mypath, bytes):
path_sep = os.path.sep.encode()
else:
path_sep = os.path.sep
@@ -122,8 +113,7 @@ def normalize_path(mypath):
if mypath.startswith(path_sep):
# posixpath.normpath collapses 3 or more leading slashes to just 1.
return os.path.normpath(2*path_sep + mypath)
- else:
- return os.path.normpath(mypath)
+ return os.path.normpath(mypath)
def grabfile(myfilename, compat_level=0, recursive=0, remember_source_file=False):
"""This function grabs the lines in a file, normalizes whitespace and returns lines in a list; if a line
@@ -259,9 +249,9 @@ def append_repo(atom_list, repo_name, remember_source_file=False):
if remember_source_file:
return [(atom.repo is not None and atom or atom.with_repo(repo_name), source) \
for atom, source in atom_list]
- else:
- return [atom.repo is not None and atom or atom.with_repo(repo_name) \
- for atom in atom_list]
+
+ return [atom.repo is not None and atom or atom.with_repo(repo_name) \
+ for atom in atom_list]
def stack_lists(lists, incremental=1, remember_source_file=False,
warn_for_unmatched_removal=False, strict_warn_for_unmatched_removal=False, ignore_repo=False):
@@ -338,8 +328,7 @@ def stack_lists(lists, incremental=1, remember_source_file=False,
if remember_source_file:
return list(new_list.items())
- else:
- return list(new_list)
+ return list(new_list)
def grabdict(myfilename, juststrings=0, empty=0, recursive=0, incremental=1, newlines=0):
"""
@@ -506,7 +495,7 @@ def grabfile_package(myfilename, compatlevel=0, recursive=0,
writemsg(_("--- Invalid atom in %s: %s\n") % (source_file, e),
noiselevel=-1)
else:
- if pkg_orig == _unicode(pkg):
+ if pkg_orig == str(pkg):
# normal atom, so return as Atom instance
if remember_source_file:
atoms.append((pkg, source_file))
@@ -598,19 +587,15 @@ def writedict(mydict, myfilename, writekey=True):
lines.append("%s %s\n" % (k, " ".join(v)))
write_atomic(myfilename, "".join(lines))
+
def shlex_split(s):
"""
This is equivalent to shlex.split, but if the current interpreter is
python2, it temporarily encodes unicode strings to bytes since python2's
shlex.split() doesn't handle unicode strings.
"""
- convert_to_bytes = sys.hexversion < 0x3000000 and not isinstance(s, bytes)
- if convert_to_bytes:
- s = _unicode_encode(s)
- rval = shlex.split(s)
- if convert_to_bytes:
- rval = [_unicode_decode(x) for x in rval]
- return rval
+ return shlex.split(s)
+
class _getconfig_shlex(shlex.shlex):
@@ -675,15 +660,9 @@ def getconfig(mycfg, tolerant=False, allow_sourcing=False, expand=True,
f = None
try:
- # NOTE: shlex doesn't support unicode objects with Python 2
- # (produces spurious \0 characters).
- if sys.hexversion < 0x3000000:
- f = open(_unicode_encode(mycfg,
- encoding=_encodings['fs'], errors='strict'), 'rb')
- else:
- f = open(_unicode_encode(mycfg,
- encoding=_encodings['fs'], errors='strict'), mode='r',
- encoding=_encodings['content'], errors='replace')
+ f = open(_unicode_encode(mycfg,
+ encoding=_encodings['fs'], errors='strict'), mode='r',
+ encoding=_encodings['content'], errors='replace')
content = f.read()
except IOError as e:
if e.errno == PermissionDenied.errno:
@@ -888,9 +867,8 @@ def varexpand(mystring, mydict=None, error_leader=None):
msg = error_leader() + msg
writemsg(msg + "\n", noiselevel=-1)
return ""
- else:
- pos += 1
- break
+ pos += 1
+ break
pos += 1
myvarname = mystring[myvstart:pos]
if braced:
@@ -900,8 +878,7 @@ def varexpand(mystring, mydict=None, error_leader=None):
msg = error_leader() + msg
writemsg(msg + "\n", noiselevel=-1)
return ""
- else:
- pos += 1
+ pos += 1
if len(myvarname) == 0:
msg = "$"
if braced:
@@ -962,7 +939,7 @@ def dump_traceback(msg, noiselevel=1):
writemsg(error+"\n", noiselevel=noiselevel)
writemsg("====================================\n\n", noiselevel=noiselevel)
-class cmp_sort_key(object):
+class cmp_sort_key:
"""
In python-3.0 the list.sort() method no longer has a "cmp" keyword
argument. This class acts as an adapter which converts a cmp function
@@ -986,7 +963,7 @@ class cmp_sort_key(object):
def __call__(self, lhs):
return self._cmp_key(self._cmp_func, lhs)
- class _cmp_key(object):
+ class _cmp_key:
__slots__ = ("_cmp_func", "_obj")
def __init__(self, cmp_func, obj):
@@ -1057,18 +1034,16 @@ def _do_stat(filename, follow_links=True):
try:
if follow_links:
return os.stat(filename)
- else:
- return os.lstat(filename)
+ return os.lstat(filename)
except OSError as oe:
func_call = "stat('%s')" % filename
if oe.errno == errno.EPERM:
raise OperationNotPermitted(func_call)
- elif oe.errno == errno.EACCES:
+ if oe.errno == errno.EACCES:
raise PermissionDenied(func_call)
- elif oe.errno == errno.ENOENT:
+ if oe.errno == errno.ENOENT:
raise FileNotFound(filename)
- else:
- raise
+ raise
def apply_permissions(filename, uid=-1, gid=-1, mode=-1, mask=-1,
stat_cached=None, follow_links=True):
@@ -1316,29 +1291,10 @@ class atomic_ofstream(ObjectProxy):
def _get_target(self):
return object.__getattribute__(self, '_file')
- if sys.hexversion >= 0x3000000:
-
- def __getattribute__(self, attr):
- if attr in ('close', 'abort', '__del__'):
- return object.__getattribute__(self, attr)
- return getattr(object.__getattribute__(self, '_file'), attr)
-
- else:
-
- # For TextIOWrapper, automatically coerce write calls to
- # unicode, in order to avoid TypeError when writing raw
- # bytes with python2.
-
- def __getattribute__(self, attr):
- if attr in ('close', 'abort', 'write', '__del__'):
- return object.__getattribute__(self, attr)
- return getattr(object.__getattribute__(self, '_file'), attr)
-
- def write(self, s):
- f = object.__getattribute__(self, '_file')
- if isinstance(f, io.TextIOWrapper):
- s = _unicode_decode(s)
- return f.write(s)
+ def __getattribute__(self, attr):
+ if attr in ('close', 'abort', '__del__'):
+ return object.__getattribute__(self, attr)
+ return getattr(object.__getattribute__(self, '_file'), attr)
def close(self):
"""Closes the temporary file, copies permissions (if possible),
@@ -1519,8 +1475,7 @@ class LazyItemsDict(UserDict):
self[item_key] = result
return result
- else:
- return UserDict.__getitem__(self, item_key)
+ return UserDict.__getitem__(self, item_key)
def __setitem__(self, item_key, value):
if item_key in self.lazy_items:
@@ -1564,7 +1519,7 @@ class LazyItemsDict(UserDict):
UserDict.__setitem__(result, k_copy, deepcopy(self[k], memo))
return result
- class _LazyItem(object):
+ class _LazyItem:
__slots__ = ('func', 'pargs', 'kwargs', 'singleton')
@@ -1599,7 +1554,7 @@ class LazyItemsDict(UserDict):
result.singleton = deepcopy(self.singleton, memo)
return result
-class ConfigProtect(object):
+class ConfigProtect:
def __init__(self, myroot, protect_list, mask_list,
case_insensitive=False):
self.myroot = myroot
diff --git a/lib/portage/util/_async/AsyncFunction.py b/lib/portage/util/_async/AsyncFunction.py
index 1dffa36cc..db77a6f43 100644
--- a/lib/portage/util/_async/AsyncFunction.py
+++ b/lib/portage/util/_async/AsyncFunction.py
@@ -1,4 +1,4 @@
-# Copyright 2015 Gentoo Foundation
+# Copyright 2015-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import pickle
@@ -23,7 +23,7 @@ class AsyncFunction(ForkProcess):
def _start(self):
pr, pw = os.pipe()
- self.fd_pipes = {}
+ self.fd_pipes = {} if self.fd_pipes is None else self.fd_pipes
self.fd_pipes[pw] = pw
self._async_func_reader_pw = pw
self._async_func_reader = PipeReader(
diff --git a/lib/portage/util/_async/BuildLogger.py b/lib/portage/util/_async/BuildLogger.py
new file mode 100644
index 000000000..f5fea77ea
--- /dev/null
+++ b/lib/portage/util/_async/BuildLogger.py
@@ -0,0 +1,109 @@
+# Copyright 2020 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+import subprocess
+
+from portage import os
+from portage.util import shlex_split
+from _emerge.AsynchronousTask import AsynchronousTask
+from portage.util._async.PipeLogger import PipeLogger
+from portage.util._async.PopenProcess import PopenProcess
+from portage.util.futures import asyncio
+from portage.util.futures.compat_coroutine import coroutine
+
+
+class BuildLogger(AsynchronousTask):
+ """
+ Write to a log file, with compression support provided by PipeLogger.
+ If the log_filter_file parameter is specified, then it is interpreted
+ as a command to execute which filters log output (see the
+ PORTAGE_LOG_FILTER_FILE_CMD variable in make.conf(5)). The stdin property
+ provides access to a writable binary file stream (refers to a pipe)
+ that log content should be written to (usually redirected from
+ subprocess stdout and stderr streams).
+ """
+
+ __slots__ = ('env', 'log_path', 'log_filter_file', '_main_task', '_stdin')
+
+ @property
+ def stdin(self):
+ return self._stdin
+
+ def _start(self):
+ filter_proc = None
+ log_input = None
+ if self.log_path is not None:
+ log_filter_file = self.log_filter_file
+ if log_filter_file is not None:
+ split_value = shlex_split(log_filter_file)
+ log_filter_file = split_value if split_value else None
+ if log_filter_file:
+ filter_input, stdin = os.pipe()
+ log_input, filter_output = os.pipe()
+ try:
+ filter_proc = PopenProcess(
+ proc=subprocess.Popen(
+ log_filter_file,
+ env=self.env,
+ stdin=filter_input,
+ stdout=filter_output,
+ stderr=filter_output,
+ ),
+ scheduler=self.scheduler,
+ )
+ filter_proc.start()
+ except EnvironmentError:
+ # Maybe the command is missing or broken somehow...
+ os.close(filter_input)
+ os.close(stdin)
+ os.close(log_input)
+ os.close(filter_output)
+ else:
+ self._stdin = os.fdopen(stdin, 'wb', 0)
+ os.close(filter_input)
+ os.close(filter_output)
+
+ if self._stdin is None:
+ # Since log_filter_file is unspecified or refers to a file
+ # that is missing or broken somehow, create a pipe that
+ # logs directly to pipe_logger.
+ log_input, stdin = os.pipe()
+ self._stdin = os.fdopen(stdin, 'wb', 0)
+
+ # Set background=True so that pipe_logger does not log to stdout.
+ pipe_logger = PipeLogger(background=True,
+ scheduler=self.scheduler, input_fd=log_input,
+ log_file_path=self.log_path)
+ pipe_logger.start()
+
+ self._main_task = asyncio.ensure_future(self._main(filter_proc, pipe_logger), loop=self.scheduler)
+ self._main_task.add_done_callback(self._main_exit)
+
+ @coroutine
+ def _main(self, filter_proc, pipe_logger):
+ try:
+ if pipe_logger.poll() is None:
+ yield pipe_logger.async_wait()
+ if filter_proc is not None and filter_proc.poll() is None:
+ yield filter_proc.async_wait()
+ except asyncio.CancelledError:
+ if pipe_logger.poll() is None:
+ pipe_logger.cancel()
+ if filter_proc is not None and filter_proc.poll() is None:
+ filter_proc.cancel()
+ raise
+
+ def _cancel(self):
+ if self._main_task is not None:
+ self._main_task.done() or self._main_task.cancel()
+ if self._stdin is not None and not self._stdin.closed:
+ self._stdin.close()
+
+ def _main_exit(self, main_task):
+ try:
+ main_task.result()
+ except asyncio.CancelledError:
+ self.cancel()
+ self._was_cancelled()
+ self.returncode = self.returncode or 0
+ self._async_wait()
diff --git a/lib/portage/util/_async/ForkProcess.py b/lib/portage/util/_async/ForkProcess.py
index d84e93833..eb01a6232 100644
--- a/lib/portage/util/_async/ForkProcess.py
+++ b/lib/portage/util/_async/ForkProcess.py
@@ -1,37 +1,123 @@
-# Copyright 2012-2013 Gentoo Foundation
+# Copyright 2012-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
+import fcntl
+import functools
+import multiprocessing
import signal
import sys
-import traceback
import portage
from portage import os
+from portage.util.futures import asyncio
+from portage.util.futures.compat_coroutine import coroutine
from _emerge.SpawnProcess import SpawnProcess
class ForkProcess(SpawnProcess):
- __slots__ = ()
+ __slots__ = ('_proc', '_proc_join_task')
+
+ # Number of seconds between poll attempts for process exit status
+ # (after the sentinel has become ready).
+ _proc_join_interval = 0.1
def _spawn(self, args, fd_pipes=None, **kwargs):
"""
- Fork a subprocess, apply local settings, and call fetch().
+ Override SpawnProcess._spawn to fork a subprocess that calls
+ self._run(). This uses multiprocessing.Process in order to leverage
+ any pre-fork and post-fork interpreter housekeeping that it provides,
+ promoting a healthy state for the forked interpreter.
"""
-
- parent_pid = os.getpid()
- pid = None
+ # Since multiprocessing.Process closes sys.__stdin__, create a
+ # temporary duplicate of fd_pipes[0] so that sys.__stdin__ can
+ # be restored in the subprocess, in case this is needed for
+ # things like PROPERTIES=interactive support.
+ stdin_dup = None
try:
- pid = os.fork()
+ stdin_fd = fd_pipes.get(0)
+ if stdin_fd is not None and stdin_fd == portage._get_stdin().fileno():
+ stdin_dup = os.dup(stdin_fd)
+ fcntl.fcntl(stdin_dup, fcntl.F_SETFD,
+ fcntl.fcntl(stdin_fd, fcntl.F_GETFD))
+ fd_pipes[0] = stdin_dup
+ self._proc = multiprocessing.Process(target=self._bootstrap, args=(fd_pipes,))
+ self._proc.start()
+ finally:
+ if stdin_dup is not None:
+ os.close(stdin_dup)
+
+ self._proc_join_task = asyncio.ensure_future(
+ self._proc_join(self._proc))
+ self._proc_join_task.add_done_callback(
+ functools.partial(self._proc_join_done, self._proc))
+
+ return [self._proc.pid]
+
+ def _cancel(self):
+ if self._proc is None:
+ super(ForkProcess, self)._cancel()
+ else:
+ self._proc.terminate()
+
+ def _async_wait(self):
+ if self._proc_join_task is None:
+ super(ForkProcess, self)._async_wait()
- if pid != 0:
- if not isinstance(pid, int):
- raise AssertionError(
- "fork returned non-integer: %s" % (repr(pid),))
- return [pid]
+ def _async_waitpid(self):
+ if self._proc_join_task is None:
+ super(ForkProcess, self)._async_waitpid()
- rval = 1
+ @coroutine
+ def _proc_join(self, proc):
+ sentinel_reader = self.scheduler.create_future()
+ self.scheduler.add_reader(proc.sentinel,
+ lambda: sentinel_reader.done() or sentinel_reader.set_result(None))
+ try:
+ yield sentinel_reader
+ finally:
+ # If multiprocessing.Process supports the close method, then
+ # access to proc.sentinel will raise ValueError if the
+ # sentinel has been closed. In this case it's not safe to call
+ # remove_reader, since the file descriptor may have been closed
+ # and then reallocated to a concurrent coroutine. When the
+ # close method is not supported, proc.sentinel remains open
+ # until proc's finalizer is called.
try:
+ self.scheduler.remove_reader(proc.sentinel)
+ except ValueError:
+ pass
+
+ # Now that proc.sentinel is ready, poll until process exit
+ # status has become available.
+ while True:
+ proc.join(0)
+ if proc.exitcode is not None:
+ break
+ yield asyncio.sleep(self._proc_join_interval)
+
+ def _proc_join_done(self, proc, future):
+ future.cancelled() or future.result()
+ self._was_cancelled()
+ if self.returncode is None:
+ self.returncode = proc.exitcode
+ self._proc = None
+ if hasattr(proc, 'close'):
+ proc.close()
+ self._proc_join_task = None
+ self._async_wait()
+
+ def _unregister(self):
+ super(ForkProcess, self)._unregister()
+ if self._proc is not None:
+ if self._proc.is_alive():
+ self._proc.terminate()
+ self._proc = None
+ if self._proc_join_task is not None:
+ self._proc_join_task.cancel()
+ self._proc_join_task = None
+
+ def _bootstrap(self, fd_pipes):
# Use default signal handlers in order to avoid problems
# killing subprocesses as reported in bug #353239.
signal.signal(signal.SIGINT, signal.SIG_DFL)
@@ -52,24 +138,22 @@ class ForkProcess(SpawnProcess):
# (see _setup_pipes docstring).
portage.process._setup_pipes(fd_pipes, close_fds=False)
- rval = self._run()
- except SystemExit:
- raise
- except:
- traceback.print_exc()
- # os._exit() skips stderr flush!
- sys.stderr.flush()
- finally:
- os._exit(rval)
+ # Since multiprocessing.Process closes sys.__stdin__ and
+ # makes sys.stdin refer to os.devnull, restore it when
+ # appropriate.
+ if 0 in fd_pipes:
+ # It's possible that sys.stdin.fileno() is already 0,
+ # and in that case the above _setup_pipes call will
+ # have already updated its identity via dup2. Otherwise,
+ # perform the dup2 call now, and also copy the file
+ # descriptor flags.
+ if sys.stdin.fileno() != 0:
+ os.dup2(0, sys.stdin.fileno())
+ fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFD,
+ fcntl.fcntl(0, fcntl.F_GETFD))
+ sys.__stdin__ = sys.stdin
- finally:
- if pid == 0 or (pid is None and os.getpid() != parent_pid):
- # Call os._exit() from a finally block in order
- # to suppress any finally blocks from earlier
- # in the call stack (see bug #345289). This
- # finally block has to be setup before the fork
- # in order to avoid a race condition.
- os._exit(1)
+ sys.exit(self._run())
def _run(self):
raise NotImplementedError(self)
diff --git a/lib/portage/util/_async/PipeLogger.py b/lib/portage/util/_async/PipeLogger.py
index a4258f350..060483f0b 100644
--- a/lib/portage/util/_async/PipeLogger.py
+++ b/lib/portage/util/_async/PipeLogger.py
@@ -1,13 +1,16 @@
-# Copyright 2008-2018 Gentoo Foundation
+# Copyright 2008-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import fcntl
import errno
import gzip
-import sys
import portage
from portage import os, _encodings, _unicode_encode
+from portage.util.futures import asyncio
+from portage.util.futures._asyncio.streams import _writer
+from portage.util.futures.compat_coroutine import coroutine
+from portage.util.futures.unix_events import _set_nonblocking
from _emerge.AbstractPollTask import AbstractPollTask
class PipeLogger(AbstractPollTask):
@@ -21,13 +24,16 @@ class PipeLogger(AbstractPollTask):
"""
__slots__ = ("input_fd", "log_file_path", "stdout_fd") + \
- ("_log_file", "_log_file_real")
+ ("_io_loop_task", "_log_file", "_log_file_nb", "_log_file_real")
def _start(self):
log_file_path = self.log_file_path
- if log_file_path is not None:
-
+ if hasattr(log_file_path, 'write'):
+ self._log_file_nb = True
+ self._log_file = log_file_path
+ _set_nonblocking(self._log_file.fileno())
+ elif log_file_path is not None:
self._log_file = open(_unicode_encode(log_file_path,
encoding=_encodings['fs'], errors='strict'), mode='ab')
if log_file_path.endswith('.gz'):
@@ -40,24 +46,15 @@ class PipeLogger(AbstractPollTask):
mode=0o660)
if isinstance(self.input_fd, int):
- fd = self.input_fd
- else:
- fd = self.input_fd.fileno()
+ self.input_fd = os.fdopen(self.input_fd, 'rb', 0)
+
+ fd = self.input_fd.fileno()
fcntl.fcntl(fd, fcntl.F_SETFL,
fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)
- # FD_CLOEXEC is enabled by default in Python >=3.4.
- if sys.hexversion < 0x3040000:
- try:
- fcntl.FD_CLOEXEC
- except AttributeError:
- pass
- else:
- fcntl.fcntl(fd, fcntl.F_SETFD,
- fcntl.fcntl(fd, fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
-
- self.scheduler.add_reader(fd, self._output_handler, fd)
+ self._io_loop_task = asyncio.ensure_future(self._io_loop(self.input_fd), loop=self.scheduler)
+ self._io_loop_task.add_done_callback(self._io_loop_done)
self._registered = True
def _cancel(self):
@@ -65,80 +62,113 @@ class PipeLogger(AbstractPollTask):
if self.returncode is None:
self.returncode = self._cancelled_returncode
- def _output_handler(self, fd):
-
+ @coroutine
+ def _io_loop(self, input_file):
background = self.background
stdout_fd = self.stdout_fd
log_file = self._log_file
+ fd = input_file.fileno()
while True:
buf = self._read_buf(fd)
if buf is None:
# not a POLLIN event, EAGAIN, etc...
- break
+ future = self.scheduler.create_future()
+ self.scheduler.add_reader(fd, future.set_result, None)
+ try:
+ yield future
+ finally:
+ # The loop and input file may have been closed.
+ if not self.scheduler.is_closed():
+ future.done() or future.cancel()
+ # Do not call remove_reader in cases where fd has
+ # been closed and then re-allocated to a concurrent
+ # coroutine as in bug 716636.
+ if not input_file.closed:
+ self.scheduler.remove_reader(fd)
+ continue
if not buf:
# EOF
- self._unregister()
- self.returncode = self.returncode or os.EX_OK
- self._async_wait()
- break
-
- else:
- if not background and stdout_fd is not None:
- failures = 0
- stdout_buf = buf
- while stdout_buf:
- try:
- stdout_buf = \
- stdout_buf[os.write(stdout_fd, stdout_buf):]
- except OSError as e:
- if e.errno != errno.EAGAIN:
- raise
- del e
- failures += 1
- if failures > 50:
- # Avoid a potentially infinite loop. In
- # most cases, the failure count is zero
- # and it's unlikely to exceed 1.
- raise
-
- # This means that a subprocess has put an inherited
- # stdio file descriptor (typically stdin) into
- # O_NONBLOCK mode. This is not acceptable (see bug
- # #264435), so revert it. We need to use a loop
- # here since there's a race condition due to
- # parallel processes being able to change the
- # flags on the inherited file descriptor.
- # TODO: When possible, avoid having child processes
- # inherit stdio file descriptors from portage
- # (maybe it can't be avoided with
- # PROPERTIES=interactive).
- fcntl.fcntl(stdout_fd, fcntl.F_SETFL,
- fcntl.fcntl(stdout_fd,
- fcntl.F_GETFL) ^ os.O_NONBLOCK)
-
- if log_file is not None:
+ return
+
+ if not background and stdout_fd is not None:
+ failures = 0
+ stdout_buf = buf
+ while stdout_buf:
+ try:
+ stdout_buf = \
+ stdout_buf[os.write(stdout_fd, stdout_buf):]
+ except OSError as e:
+ if e.errno != errno.EAGAIN:
+ raise
+ del e
+ failures += 1
+ if failures > 50:
+ # Avoid a potentially infinite loop. In
+ # most cases, the failure count is zero
+ # and it's unlikely to exceed 1.
+ raise
+
+ # This means that a subprocess has put an inherited
+ # stdio file descriptor (typically stdin) into
+ # O_NONBLOCK mode. This is not acceptable (see bug
+ # #264435), so revert it. We need to use a loop
+ # here since there's a race condition due to
+ # parallel processes being able to change the
+ # flags on the inherited file descriptor.
+ # TODO: When possible, avoid having child processes
+ # inherit stdio file descriptors from portage
+ # (maybe it can't be avoided with
+ # PROPERTIES=interactive).
+ fcntl.fcntl(stdout_fd, fcntl.F_SETFL,
+ fcntl.fcntl(stdout_fd,
+ fcntl.F_GETFL) ^ os.O_NONBLOCK)
+
+ if log_file is not None:
+ if self._log_file_nb:
+ # Use the _writer function which uses os.write, since the
+ # log_file.write method looses data when an EAGAIN occurs.
+ yield _writer(log_file, buf, loop=self.scheduler)
+ else:
+ # For gzip.GzipFile instances, the above _writer function
+ # will not work because data written directly to the file
+ # descriptor bypasses compression.
log_file.write(buf)
log_file.flush()
+ def _io_loop_done(self, future):
+ try:
+ future.result()
+ except asyncio.CancelledError:
+ self.cancel()
+ self._was_cancelled()
+ self.returncode = self.returncode or os.EX_OK
+ self._async_wait()
+
def _unregister(self):
if self.input_fd is not None:
if isinstance(self.input_fd, int):
- self.scheduler.remove_reader(self.input_fd)
os.close(self.input_fd)
- else:
+ elif not self.input_fd.closed:
self.scheduler.remove_reader(self.input_fd.fileno())
self.input_fd.close()
self.input_fd = None
+ if self._io_loop_task is not None:
+ if not self.scheduler.is_closed():
+ self._io_loop_task.done() or self._io_loop_task.cancel()
+ self._io_loop_task = None
+
if self.stdout_fd is not None:
os.close(self.stdout_fd)
self.stdout_fd = None
if self._log_file is not None:
- self._log_file.close()
+ if not self._log_file.closed:
+ self.scheduler.remove_writer(self._log_file.fileno())
+ self._log_file.close()
self._log_file = None
if self._log_file_real is not None:
diff --git a/lib/portage/util/_async/SchedulerInterface.py b/lib/portage/util/_async/SchedulerInterface.py
index ec6417da1..3ff250d1d 100644
--- a/lib/portage/util/_async/SchedulerInterface.py
+++ b/lib/portage/util/_async/SchedulerInterface.py
@@ -1,4 +1,4 @@
-# Copyright 2012-2018 Gentoo Foundation
+# Copyright 2012-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import gzip
@@ -7,6 +7,8 @@ import errno
from portage import _encodings
from portage import _unicode_encode
from portage.util import writemsg_level
+from portage.util.futures._asyncio.streams import _writer
+from portage.util.futures.compat_coroutine import coroutine
from ..SlotObject import SlotObject
class SchedulerInterface(SlotObject):
@@ -53,6 +55,34 @@ class SchedulerInterface(SlotObject):
def _return_false():
return False
+ @coroutine
+ def async_output(self, msg, log_file=None, background=None,
+ level=0, noiselevel=-1):
+ """
+ Output a msg to stdio (if not in background) and to a log file
+ if provided.
+
+ @param msg: a message string, including newline if appropriate
+ @type msg: str
+ @param log_file: log file in binary mode
+ @type log_file: file
+ @param background: send messages only to log (not to stdio)
+ @type background: bool
+ @param level: a numeric logging level (see the logging module)
+ @type level: int
+ @param noiselevel: passed directly to writemsg
+ @type noiselevel: int
+ """
+ global_background = self._is_background()
+ if background is None or global_background:
+ background = global_background
+
+ if not background:
+ writemsg_level(msg, level=level, noiselevel=noiselevel)
+
+ if log_file is not None:
+ yield _writer(log_file, _unicode_encode(msg))
+
def output(self, msg, log_path=None, background=None,
level=0, noiselevel=-1):
"""
diff --git a/lib/portage/util/_compare_files.py b/lib/portage/util/_compare_files.py
index bd993e501..de97a9d9d 100644
--- a/lib/portage/util/_compare_files.py
+++ b/lib/portage/util/_compare_files.py
@@ -1,4 +1,4 @@
-# Copyright 2019 Gentoo Authors
+# Copyright 2019-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
__all__ = ["compare_files"]
@@ -6,7 +6,6 @@ __all__ = ["compare_files"]
import io
import os
import stat
-import sys
from portage import _encodings
from portage import _unicode_encode
@@ -49,20 +48,12 @@ def compare_files(file1, file2, skipped_types=()):
if "xattr" not in skipped_types and sorted(xattr.get_all(file1, nofollow=True)) != sorted(xattr.get_all(file2, nofollow=True)):
differences.append("xattr")
- if sys.hexversion >= 0x3030000:
- if "atime" not in skipped_types and file1_stat.st_atime_ns != file2_stat.st_atime_ns:
- differences.append("atime")
- if "mtime" not in skipped_types and file1_stat.st_mtime_ns != file2_stat.st_mtime_ns:
- differences.append("mtime")
- if "ctime" not in skipped_types and file1_stat.st_ctime_ns != file2_stat.st_ctime_ns:
- differences.append("ctime")
- else:
- if "atime" not in skipped_types and file1_stat.st_atime != file2_stat.st_atime:
- differences.append("atime")
- if "mtime" not in skipped_types and file1_stat.st_mtime != file2_stat.st_mtime:
- differences.append("mtime")
- if "ctime" not in skipped_types and file1_stat.st_ctime != file2_stat.st_ctime:
- differences.append("ctime")
+ if "atime" not in skipped_types and file1_stat.st_atime_ns != file2_stat.st_atime_ns:
+ differences.append("atime")
+ if "mtime" not in skipped_types and file1_stat.st_mtime_ns != file2_stat.st_mtime_ns:
+ differences.append("mtime")
+ if "ctime" not in skipped_types and file1_stat.st_ctime_ns != file2_stat.st_ctime_ns:
+ differences.append("ctime")
if "type" in differences:
pass
diff --git a/lib/portage/util/_desktop_entry.py b/lib/portage/util/_desktop_entry.py
index ee6572588..74053a30f 100644
--- a/lib/portage/util/_desktop_entry.py
+++ b/lib/portage/util/_desktop_entry.py
@@ -1,7 +1,6 @@
# Copyright 2012-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-import io
import re
import subprocess
import sys
@@ -25,7 +24,12 @@ def parse_desktop_entry(path):
return parser
-_trivial_warnings = re.compile(r' looks redundant with value ')
+_trivial_warnings = re.compile(r' looks '
+ # >=desktop-file-utils-0.25
+ r'(?:the same as that of key|'
+
+ # <desktop-file-utils-0.25
+ r'redundant with value) ')
_ignored_errors = (
# Ignore error for emacs.desktop:
diff --git a/lib/portage/util/_dyn_libs/LinkageMapELF.py b/lib/portage/util/_dyn_libs/LinkageMapELF.py
index 473a1243d..954a956c6 100644
--- a/lib/portage/util/_dyn_libs/LinkageMapELF.py
+++ b/lib/portage/util/_dyn_libs/LinkageMapELF.py
@@ -6,7 +6,6 @@ import errno
import itertools
import logging
import subprocess
-import sys
import portage
from portage import _encodings
@@ -27,10 +26,6 @@ from portage.util import writemsg_level
from portage.util._dyn_libs.NeededEntry import NeededEntry
from portage.util.elf.header import ELFHeader
-if sys.hexversion >= 0x3000000:
- _unicode = str
-else:
- _unicode = unicode
# Map ELF e_machine values from NEEDED.ELF.2 to approximate multilib
# categories. This approximation will produce incorrect results on x32
@@ -55,7 +50,7 @@ _approx_multilib_categories = {
"X86_64": "x86_64",
}
-class LinkageMapELF(object):
+class LinkageMapELF:
"""Models dynamic linker dependencies."""
@@ -63,7 +58,7 @@ class LinkageMapELF(object):
_soname_map_class = slot_dict_class(
("consumers", "providers"), prefix="")
- class _obj_properties_class(object):
+ class _obj_properties_class:
__slots__ = ("arch", "needed", "runpaths", "soname", "alt_paths",
"owner",)
@@ -106,7 +101,7 @@ class LinkageMapELF(object):
self._obj_key_cache[path] = key
return key
- class _ObjectKey(object):
+ class _ObjectKey:
"""Helper class used as _obj_properties keys for objects."""
@@ -333,7 +328,7 @@ class LinkageMapELF(object):
entry.multilib_category = compute_multilib_category(elf_header)
entry.filename = entry.filename[root_len:]
owner = plibs.pop(entry.filename, None)
- lines.append((owner, "scanelf", _unicode(entry)))
+ lines.append((owner, "scanelf", str(entry)))
proc.wait()
proc.stdout.close()
@@ -489,7 +484,7 @@ class LinkageMapELF(object):
os = _os_merge
- class _LibraryCache(object):
+ class _LibraryCache:
"""
Caches properties associated with paths.
@@ -520,24 +515,23 @@ class LinkageMapELF(object):
"""
if obj in cache_self.cache:
return cache_self.cache[obj]
- else:
- obj_key = self._obj_key(obj)
- # Check that the library exists on the filesystem.
- if obj_key.file_exists():
- # Get the arch and soname from LinkageMap._obj_properties if
- # it exists. Otherwise, None.
- obj_props = self._obj_properties.get(obj_key)
- if obj_props is None:
- arch = None
- soname = None
- else:
- arch = obj_props.arch
- soname = obj_props.soname
- return cache_self.cache.setdefault(obj, \
- (arch, soname, obj_key, True))
+
+ obj_key = self._obj_key(obj)
+ # Check that the library exists on the filesystem.
+ if obj_key.file_exists():
+ # Get the arch and soname from LinkageMap._obj_properties if
+ # it exists. Otherwise, None.
+ obj_props = self._obj_properties.get(obj_key)
+ if obj_props is None:
+ arch = None
+ soname = None
else:
- return cache_self.cache.setdefault(obj, \
- (None, None, obj_key, False))
+ arch = obj_props.arch
+ soname = obj_props.soname
+ return cache_self.cache.setdefault(obj, \
+ (arch, soname, obj_key, True))
+ return cache_self.cache.setdefault(obj, \
+ (None, None, obj_key, False))
rValue = {}
cache = _LibraryCache()
diff --git a/lib/portage/util/_dyn_libs/NeededEntry.py b/lib/portage/util/_dyn_libs/NeededEntry.py
index 70ff99100..20dc2f779 100644
--- a/lib/portage/util/_dyn_libs/NeededEntry.py
+++ b/lib/portage/util/_dyn_libs/NeededEntry.py
@@ -1,15 +1,12 @@
# Copyright 2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
-import sys
from portage import _encodings, _unicode_encode
from portage.exception import InvalidData
from portage.localization import _
-class NeededEntry(object):
+class NeededEntry:
"""
Represents one entry (line) from a NEEDED.ELF.2 file. The entry
must have 5 or more semicolon-delimited fields in order to be
@@ -75,13 +72,3 @@ class NeededEntry(object):
(self.multilib_category if self.multilib_category
is not None else "")
]) + "\n"
-
- if sys.hexversion < 0x3000000:
-
- __unicode__ = __str__
-
- def __str__(self):
- return _unicode_encode(self.__unicode__(),
- encoding=_encodings['content'])
-
- __str__.__doc__ = __unicode__.__doc__
diff --git a/lib/portage/util/_dyn_libs/PreservedLibsRegistry.py b/lib/portage/util/_dyn_libs/PreservedLibsRegistry.py
index f83b82a31..d6f1d5e29 100644
--- a/lib/portage/util/_dyn_libs/PreservedLibsRegistry.py
+++ b/lib/portage/util/_dyn_libs/PreservedLibsRegistry.py
@@ -1,16 +1,11 @@
-# Copyright 1998-2014 Gentoo Foundation
+# Copyright 1998-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import errno
import json
import logging
+import pickle
import stat
-import sys
-
-try:
- import cPickle as pickle
-except ImportError:
- import pickle
from portage import abssymlink
from portage import os
@@ -25,11 +20,8 @@ from portage.util import writemsg_level
from portage.versions import cpv_getkey
from portage.locks import lockfile, unlockfile
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
-class PreservedLibsRegistry(object):
+class PreservedLibsRegistry:
""" This class handles the tracking of preserved library objects """
# JSON read support has been available since portage-2.2.0_alpha89.
@@ -38,11 +30,8 @@ class PreservedLibsRegistry(object):
_json_write_opts = {
"ensure_ascii": False,
"indent": "\t",
- "sort_keys": True
+ "sort_keys": True,
}
- if sys.hexversion < 0x30200F0:
- # indent only supports int number of spaces
- _json_write_opts["indent"] = 4
def __init__(self, root, filename):
"""
@@ -154,7 +143,7 @@ class PreservedLibsRegistry(object):
int conversion and a possible ValueError resulting
from vardb corruption.
"""
- if not isinstance(counter, basestring):
+ if not isinstance(counter, str):
counter = str(counter)
return _unicode_decode(counter).strip()
diff --git a/lib/portage/util/_dyn_libs/soname_deps.py b/lib/portage/util/_dyn_libs/soname_deps.py
index 544cbc8f1..9010abb27 100644
--- a/lib/portage/util/_dyn_libs/soname_deps.py
+++ b/lib/portage/util/_dyn_libs/soname_deps.py
@@ -1,8 +1,6 @@
# Copyright 2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
import collections
import fnmatch
import functools
@@ -17,7 +15,7 @@ from portage.util import (
)
-class SonameDepsProcessor(object):
+class SonameDepsProcessor:
"""
Processes NEEDED.ELF.2 entries for one package, in order to generate
REQUIRES and PROVIDES metadata.
diff --git a/lib/portage/util/_eventloop/EventLoop.py b/lib/portage/util/_eventloop/EventLoop.py
index ffd12cff9..b111238a6 100644
--- a/lib/portage/util/_eventloop/EventLoop.py
+++ b/lib/portage/util/_eventloop/EventLoop.py
@@ -1,4 +1,4 @@
-# Copyright 1999-2018 Gentoo Foundation
+# Copyright 1999-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
from __future__ import division
@@ -10,13 +10,10 @@ import logging
import os
import select
import signal
-import sys
+import time
import traceback
-try:
- import asyncio as _real_asyncio
-except ImportError:
- _real_asyncio = None
+import asyncio as _real_asyncio
try:
import fcntl
@@ -37,12 +34,11 @@ portage.proxy.lazyimport.lazyimport(globals(),
)
from portage.util import writemsg_level
-from portage.util.monotonic import monotonic
from ..SlotObject import SlotObject
from .PollConstants import PollConstants
from .PollSelectAdapter import PollSelectAdapter
-class EventLoop(object):
+class EventLoop:
"""
An event loop, intended to be compatible with the GLib event loop.
Call the iteration method in order to execute one iteration of the
@@ -69,7 +65,7 @@ class EventLoop(object):
__slots__ = ("args", "function", "calling", "interval", "source_id",
"timestamp")
- class _handle(object):
+ class _handle:
"""
A callback wrapper object, compatible with asyncio.Handle.
"""
@@ -86,7 +82,7 @@ class EventLoop(object):
"""
self._loop.source_remove(self._callback_id)
- class _call_soon_callback(object):
+ class _call_soon_callback:
"""
Wraps a call_soon callback, and always returns False, since these
callbacks are only supposed to run once.
@@ -101,7 +97,7 @@ class EventLoop(object):
self._callback(*self._args)
return False
- class _selector_callback(object):
+ class _selector_callback:
"""
Wraps an callback, and always returns True, for callbacks that
are supposed to run repeatedly.
@@ -168,18 +164,6 @@ class EventLoop(object):
# IOError: [Errno 38] Function not implemented
pass
else:
-
- # FD_CLOEXEC is enabled by default in Python >=3.4.
- if sys.hexversion < 0x3040000 and fcntl is not None:
- try:
- fcntl.FD_CLOEXEC
- except AttributeError:
- pass
- else:
- fcntl.fcntl(epoll_obj.fileno(), fcntl.F_SETFD,
- fcntl.fcntl(epoll_obj.fileno(),
- fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
-
self._poll_obj = _epoll_adapter(epoll_obj)
self.IO_ERR = select.EPOLLERR
self.IO_HUP = select.EPOLLHUP
@@ -432,17 +416,6 @@ class EventLoop(object):
fcntl.fcntl(self._sigchld_read,
fcntl.F_GETFL) | os.O_NONBLOCK)
- # FD_CLOEXEC is enabled by default in Python >=3.4.
- if sys.hexversion < 0x3040000:
- try:
- fcntl.FD_CLOEXEC
- except AttributeError:
- pass
- else:
- fcntl.fcntl(self._sigchld_read, fcntl.F_SETFD,
- fcntl.fcntl(self._sigchld_read,
- fcntl.F_GETFD) | fcntl.FD_CLOEXEC)
-
# The IO watch is dynamically registered and unregistered as
# needed, since we don't want to consider it as a valid source
# of events when there are no child listeners. It's important
@@ -887,7 +860,7 @@ class EventLoop(object):
epoch, precision, accuracy and drift are unspecified and may
differ per event loop.
"""
- return monotonic()
+ return time.monotonic()
def call_later(self, delay, callback, *args, **kwargs):
"""
@@ -985,9 +958,8 @@ class EventLoop(object):
executor = ForkExecutor(loop=self)
self._default_executor = executor
future = executor.submit(func, *args)
- if _real_asyncio is not None:
- future = _real_asyncio.wrap_future(future,
- loop=self._asyncio_wrapper)
+ future = _real_asyncio.wrap_future(future,
+ loop=self._asyncio_wrapper)
return future
def is_running(self):
@@ -1148,7 +1120,7 @@ def create_poll_instance():
return select.poll()
return PollSelectAdapter()
-class _epoll_adapter(object):
+class _epoll_adapter:
"""
Wraps a select.epoll instance in order to make it compatible
with select.poll instances. This is necessary since epoll instances
diff --git a/lib/portage/util/_eventloop/PollConstants.py b/lib/portage/util/_eventloop/PollConstants.py
index d0270a996..c5700d108 100644
--- a/lib/portage/util/_eventloop/PollConstants.py
+++ b/lib/portage/util/_eventloop/PollConstants.py
@@ -2,7 +2,7 @@
# Distributed under the terms of the GNU General Public License v2
import select
-class PollConstants(object):
+class PollConstants:
"""
Provides POLL* constants that are equivalent to those from the
@@ -15,4 +15,3 @@ class PollConstants(object):
locals()[k] = getattr(select, k, v)
v *= 2
del k, v
-
diff --git a/lib/portage/util/_eventloop/PollSelectAdapter.py b/lib/portage/util/_eventloop/PollSelectAdapter.py
index 32b404b67..08dc664a4 100644
--- a/lib/portage/util/_eventloop/PollSelectAdapter.py
+++ b/lib/portage/util/_eventloop/PollSelectAdapter.py
@@ -6,7 +6,7 @@ from __future__ import division
from .PollConstants import PollConstants
import select
-class PollSelectAdapter(object):
+class PollSelectAdapter:
"""
Use select to emulate a poll object, for
@@ -73,4 +73,3 @@ class PollSelectAdapter(object):
for fd in select_events[0]:
poll_events.append((fd, PollConstants.POLLIN))
return poll_events
-
diff --git a/lib/portage/util/_eventloop/asyncio_event_loop.py b/lib/portage/util/_eventloop/asyncio_event_loop.py
index ce7e06923..605e7243b 100644
--- a/lib/portage/util/_eventloop/asyncio_event_loop.py
+++ b/lib/portage/util/_eventloop/asyncio_event_loop.py
@@ -4,13 +4,8 @@
import os
import signal
-try:
- import asyncio as _real_asyncio
- from asyncio.events import AbstractEventLoop as _AbstractEventLoop
-except ImportError:
- # Allow ImportModulesTestCase to succeed.
- _real_asyncio = None
- _AbstractEventLoop = object
+import asyncio as _real_asyncio
+from asyncio.events import AbstractEventLoop as _AbstractEventLoop
import portage
diff --git a/lib/portage/util/_eventloop/global_event_loop.py b/lib/portage/util/_eventloop/global_event_loop.py
index 2f6371dc1..1db958d2e 100644
--- a/lib/portage/util/_eventloop/global_event_loop.py
+++ b/lib/portage/util/_eventloop/global_event_loop.py
@@ -1,22 +1,16 @@
-# Copyright 2012 Gentoo Foundation
+# Copyright 2012-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import os
-import sys
from .EventLoop import EventLoop
from portage.util._eventloop.asyncio_event_loop import AsyncioEventLoop
-_asyncio_enabled = sys.version_info >= (3, 4)
-_default_constructor = AsyncioEventLoop if _asyncio_enabled else EventLoop
-
-# If _default_constructor doesn't support multiprocessing,
-# then _multiprocessing_constructor is used in subprocesses.
-_multiprocessing_constructor = EventLoop
_MAIN_PID = os.getpid()
_instances = {}
+
def global_event_loop():
"""
Get a global EventLoop (or compatible object) instance which
@@ -28,9 +22,11 @@ def global_event_loop():
if instance is not None:
return instance
- constructor = _default_constructor
+ constructor = AsyncioEventLoop
+ # If the default constructor doesn't support multiprocessing,
+ # then multiprocessing constructor is used in subprocesses.
if not constructor.supports_multiprocessing and pid != _MAIN_PID:
- constructor = _multiprocessing_constructor
+ constructor = EventLoop
# Use the _asyncio_wrapper attribute, so that unit tests can compare
# the reference to one retured from _wrap_loop(), since they should
diff --git a/lib/portage/util/_urlopen.py b/lib/portage/util/_urlopen.py
index 1d8ba3fd3..b46d1554c 100644
--- a/lib/portage/util/_urlopen.py
+++ b/lib/portage/util/_urlopen.py
@@ -1,24 +1,14 @@
-# Copyright 2012-2019 Gentoo Authors
+# Copyright 2012-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import io
-import sys
from datetime import datetime
from time import mktime
from email.utils import formatdate, parsedate
+from urllib.request import urlopen as _urlopen
+import urllib.parse as urllib_parse
+import urllib.request as urllib_request
-try:
- from urllib.request import urlopen as _urlopen
- import urllib.parse as urllib_parse
- import urllib.request as urllib_request
-except ImportError:
- from urllib import urlopen as _urlopen
- import urlparse as urllib_parse
- import urllib2 as urllib_request
-
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- long = int
# to account for the difference between TIMESTAMP of the index' contents
# and the file-'mtime'
@@ -40,37 +30,36 @@ def urlopen(url, if_modified_since=None):
parse_result = urllib_parse.urlparse(url)
if parse_result.scheme not in ("http", "https"):
return _urlopen(url)
- else:
- netloc = parse_result.netloc.rpartition('@')[-1]
- url = urllib_parse.urlunparse((parse_result.scheme, netloc, parse_result.path, parse_result.params, parse_result.query, parse_result.fragment))
- password_manager = urllib_request.HTTPPasswordMgrWithDefaultRealm()
- request = urllib_request.Request(url)
- request.add_header('User-Agent', 'Gentoo Portage')
- if if_modified_since:
- request.add_header('If-Modified-Since', _timestamp_to_http(if_modified_since))
- if parse_result.username is not None:
- password_manager.add_password(None, url, parse_result.username, parse_result.password)
- auth_handler = CompressedResponseProcessor(password_manager)
- opener = urllib_request.build_opener(auth_handler)
- hdl = opener.open(request)
- if hdl.headers.get('last-modified', ''):
- try:
- add_header = hdl.headers.add_header
- except AttributeError:
- # Python 2
- add_header = hdl.headers.addheader
- add_header('timestamp', _http_to_timestamp(hdl.headers.get('last-modified')))
- return hdl
+
+ netloc = parse_result.netloc.rpartition('@')[-1]
+ url = urllib_parse.urlunparse((parse_result.scheme, netloc, parse_result.path, parse_result.params, parse_result.query, parse_result.fragment))
+ password_manager = urllib_request.HTTPPasswordMgrWithDefaultRealm()
+ request = urllib_request.Request(url)
+ request.add_header('User-Agent', 'Gentoo Portage')
+ if if_modified_since:
+ request.add_header('If-Modified-Since', _timestamp_to_http(if_modified_since))
+ if parse_result.username is not None:
+ password_manager.add_password(None, url, parse_result.username, parse_result.password)
+ auth_handler = CompressedResponseProcessor(password_manager)
+ opener = urllib_request.build_opener(auth_handler)
+ hdl = opener.open(request)
+ if hdl.headers.get('last-modified', ''):
+ try:
+ add_header = hdl.headers.add_header
+ except AttributeError:
+ # Python 2
+ add_header = hdl.headers.addheader
+ add_header('timestamp', _http_to_timestamp(hdl.headers.get('last-modified')))
+ return hdl
def _timestamp_to_http(timestamp):
- dt = datetime.fromtimestamp(float(long(timestamp)+TIMESTAMP_TOLERANCE))
+ dt = datetime.fromtimestamp(float(int(timestamp)+TIMESTAMP_TOLERANCE))
stamp = mktime(dt.timetuple())
return formatdate(timeval=stamp, localtime=False, usegmt=True)
def _http_to_timestamp(http_datetime_string):
- tuple = parsedate(http_datetime_string)
- timestamp = mktime(tuple)
- return str(long(timestamp))
+ timestamp = mktime(parsedate(http_datetime_string))
+ return str(int(timestamp))
class CompressedResponseProcessor(urllib_request.HTTPBasicAuthHandler):
# Handler for compressed responses.
diff --git a/lib/portage/util/_xattr.py b/lib/portage/util/_xattr.py
index c118589a3..531c61efb 100644
--- a/lib/portage/util/_xattr.py
+++ b/lib/portage/util/_xattr.py
@@ -20,7 +20,7 @@ import subprocess
from portage.exception import OperationNotSupported
-class _XattrGetAll(object):
+class _XattrGetAll:
"""Implement get_all() using list()/get() if there is no easy bulk method"""
@classmethod
diff --git a/lib/portage/util/backoff.py b/lib/portage/util/backoff.py
index ee39007ef..73f69d6db 100644
--- a/lib/portage/util/backoff.py
+++ b/lib/portage/util/backoff.py
@@ -10,7 +10,7 @@ import random
import sys
-class ExponentialBackoff(object):
+class ExponentialBackoff:
"""
An object that when called with number of previous tries, calculates
an exponential delay for the next try.
diff --git a/lib/portage/util/changelog.py b/lib/portage/util/changelog.py
index 9fc5ab6df..362cf7717 100644
--- a/lib/portage/util/changelog.py
+++ b/lib/portage/util/changelog.py
@@ -1,21 +1,21 @@
#!/usr/bin/python -b
-# Copyright 2009-2015 Gentoo Foundation
+# Copyright 2009-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
from portage.manifest import guessManifestFileType
-from portage.versions import _unicode, pkgsplit, vercmp
+from portage.versions import pkgsplit, vercmp
-class ChangeLogTypeSort(_unicode):
+class ChangeLogTypeSort(str):
"""
Helps to sort file names by file type and other criteria.
"""
def __new__(cls, status_change, file_name):
- return _unicode.__new__(cls, status_change + file_name)
+ return str.__new__(cls, status_change + file_name)
def __init__(self, status_change, file_name):
- _unicode.__init__(status_change + file_name)
+ str.__init__(status_change + file_name)
self.status_change = status_change
self.file_name = file_name
self.file_type = guessManifestFileType(file_name)
@@ -32,16 +32,15 @@ class ChangeLogTypeSort(_unicode):
if first == "EBUILD":
return True
- elif first == "MISC":
+ if first == "MISC":
return second in ("EBUILD",)
- elif first == "AUX":
+ if first == "AUX":
return second in ("EBUILD", "MISC")
- elif first == "DIST":
+ if first == "DIST":
return second in ("EBUILD", "MISC", "AUX")
- elif first is None:
+ if first is None:
return False
- else:
- raise ValueError("Unknown file type '%s'" % first)
+ raise ValueError("Unknown file type '%s'" % first)
def __lt__(self, other):
"""
@@ -55,7 +54,7 @@ class ChangeLogTypeSort(_unicode):
# Sort by file type as defined by _file_type_lt().
if self._file_type_lt(self, other):
return True
- elif self._file_type_lt(other, self):
+ if self._file_type_lt(other, self):
return False
# Files have the same type.
@@ -64,6 +63,6 @@ class ChangeLogTypeSort(_unicode):
ver = "-".join(pkgsplit(self.file_name[:-7])[1:3])
other_ver = "-".join(pkgsplit(other.file_name[:-7])[1:3])
return vercmp(ver, other_ver) < 0
- else:
- # Sort lexicographically.
- return self.file_name < other.file_name
+
+ # Sort lexicographically.
+ return self.file_name < other.file_name
diff --git a/lib/portage/util/compression_probe.py b/lib/portage/util/compression_probe.py
index 7d595670b..6c2140794 100644
--- a/lib/portage/util/compression_probe.py
+++ b/lib/portage/util/compression_probe.py
@@ -4,10 +4,7 @@
import ctypes
import errno
import re
-import sys
-if sys.hexversion >= 0x3000000:
- basestring = str
from portage import _encodings, _unicode_encode
from portage.exception import FileNotFound, PermissionDenied
@@ -87,7 +84,7 @@ def compression_probe(f):
@rtype str or None
"""
- open_file = isinstance(f, basestring)
+ open_file = isinstance(f, str)
if open_file:
try:
f = open(_unicode_encode(f,
diff --git a/lib/portage/util/configparser.py b/lib/portage/util/configparser.py
index c4c92a603..8563d5c8c 100644
--- a/lib/portage/util/configparser.py
+++ b/lib/portage/util/configparser.py
@@ -1,4 +1,4 @@
-# Copyright 2016 Gentoo Foundation
+# Copyright 2016-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
__all__ = ['ConfigParserError', 'NoOptionError', 'ParsingError',
@@ -9,28 +9,15 @@ __all__ = ['ConfigParserError', 'NoOptionError', 'ParsingError',
# - RawConfigParser that provides no interpolation for values.
import io
-import sys
-try:
- from configparser import (Error as ConfigParserError,
- NoOptionError, ParsingError, RawConfigParser)
- if sys.hexversion >= 0x3020000:
- from configparser import ConfigParser as SafeConfigParser
- else:
- from configparser import SafeConfigParser
-except ImportError:
- from ConfigParser import (Error as ConfigParserError,
- NoOptionError, ParsingError, RawConfigParser, SafeConfigParser)
+from configparser import (Error as ConfigParserError,
+ NoOptionError, ParsingError, RawConfigParser)
+from configparser import ConfigParser as SafeConfigParser
from portage import _encodings
from portage import _unicode_encode
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
-
-
def read_configs(parser, paths):
"""
Read configuration files from given paths into the specified
@@ -50,7 +37,7 @@ def read_configs(parser, paths):
source_kwarg = 'filename'
for p in paths:
- if isinstance(p, basestring):
+ if isinstance(p, str):
f = None
try:
f = io.open(_unicode_encode(p,
diff --git a/lib/portage/util/digraph.py b/lib/portage/util/digraph.py
index d279b7867..c262cddee 100644
--- a/lib/portage/util/digraph.py
+++ b/lib/portage/util/digraph.py
@@ -1,17 +1,14 @@
# Copyright 2010-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
__all__ = ['digraph']
import bisect
from collections import deque
-import sys
from portage.util import writemsg
-class digraph(object):
+class digraph:
"""
A directed graph object.
"""
@@ -385,6 +382,3 @@ class digraph(object):
__contains__ = contains
empty = is_empty
copy = clone
-
- if sys.hexversion < 0x3000000:
- __nonzero__ = __bool__
diff --git a/lib/portage/util/elf/header.py b/lib/portage/util/elf/header.py
index 3d2307402..bedb19eab 100644
--- a/lib/portage/util/elf/header.py
+++ b/lib/portage/util/elf/header.py
@@ -6,7 +6,7 @@ from portage.util.endian.decode import (decode_uint16_le,
from portage.util.elf.constants import (E_ENTRY, E_MACHINE, E_TYPE,
EI_CLASS, ELFCLASS32, ELFCLASS64, ELFDATA2LSB, ELFDATA2MSB)
-class ELFHeader(object):
+class ELFHeader:
__slots__ = ('e_flags', 'e_machine', 'e_type', 'ei_class',
'ei_data')
diff --git a/lib/portage/util/env_update.py b/lib/portage/util/env_update.py
index a69114d80..59f5bb9cc 100644
--- a/lib/portage/util/env_update.py
+++ b/lib/portage/util/env_update.py
@@ -1,4 +1,4 @@
-# Copyright 2010-2014 Gentoo Foundation
+# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
__all__ = ['env_update']
@@ -7,7 +7,6 @@ import errno
import glob
import io
import stat
-import sys
import time
import portage
@@ -23,9 +22,6 @@ from portage.util.listdir import listdir
from portage.dbapi.vartree import vartree
from portage.package.ebuild.config import config
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- long = int
def env_update(makelinks=1, target_root=None, prev_mtimes=None, contents=None,
env=None, writemsg_level=None, vardbapi=None):
@@ -257,7 +253,7 @@ def _env_update(makelinks, target_root, prev_mtimes, contents, env,
if e.errno != errno.ENOENT:
raise
- current_time = long(time.time())
+ current_time = int(time.time())
mtime_changed = False
lib_dirs = set()
diff --git a/lib/portage/util/formatter.py b/lib/portage/util/formatter.py
index ce6799e3f..8180a662c 100644
--- a/lib/portage/util/formatter.py
+++ b/lib/portage/util/formatter.py
@@ -7,7 +7,7 @@
import sys
-class AbstractFormatter(object):
+class AbstractFormatter:
"""The standard formatter."""
def __init__(self, writer):
@@ -35,7 +35,7 @@ class AbstractFormatter(object):
self.writer.new_styles(tuple(self.style_stack))
-class NullWriter(object):
+class NullWriter:
"""Minimal writer interface to use in testing & inheritance.
A writer which only provides the interface definition; no actions are
@@ -66,4 +66,3 @@ class DumbWriter(NullWriter):
def send_literal_data(self, data):
self.file.write(data)
-
diff --git a/lib/portage/util/futures/_asyncio/__init__.py b/lib/portage/util/futures/_asyncio/__init__.py
index f4b03891f..a902ad895 100644
--- a/lib/portage/util/futures/_asyncio/__init__.py
+++ b/lib/portage/util/futures/_asyncio/__init__.py
@@ -23,10 +23,7 @@ __all__ = (
import subprocess
import sys
-try:
- import asyncio as _real_asyncio
-except ImportError:
- _real_asyncio = None
+import asyncio as _real_asyncio
try:
import threading
@@ -41,15 +38,16 @@ portage.proxy.lazyimport.lazyimport(globals(),
)
from portage.util._eventloop.asyncio_event_loop import AsyncioEventLoop as _AsyncioEventLoop
from portage.util._eventloop.global_event_loop import (
- _asyncio_enabled,
global_event_loop as _global_event_loop,
)
+# pylint: disable=redefined-builtin
from portage.util.futures.futures import (
CancelledError,
Future,
InvalidStateError,
TimeoutError,
)
+# pylint: enable=redefined-builtin
from portage.util.futures._asyncio.process import _Process
from portage.util.futures._asyncio.tasks import (
ALL_COMPLETED,
@@ -101,19 +99,14 @@ def get_event_loop():
def get_child_watcher():
- """Equivalent to calling get_event_loop_policy().get_child_watcher()."""
- return get_event_loop_policy().get_child_watcher()
+ """Equivalent to calling get_event_loop_policy().get_child_watcher()."""
+ return get_event_loop_policy().get_child_watcher()
def set_child_watcher(watcher):
- """Equivalent to calling
- get_event_loop_policy().set_child_watcher(watcher)."""
- return get_event_loop_policy().set_child_watcher(watcher)
-
-
-# Python 3.4 and later implement PEP 446, which makes newly
-# created file descriptors non-inheritable by default.
-_close_fds_default = sys.version_info < (3, 4)
+ """Equivalent to calling
+ get_event_loop_policy().set_child_watcher(watcher)."""
+ return get_event_loop_policy().set_child_watcher(watcher)
def create_subprocess_exec(*args, **kwargs):
@@ -138,8 +131,10 @@ def create_subprocess_exec(*args, **kwargs):
@return: subset of asyncio.subprocess.Process interface
"""
loop = _wrap_loop(kwargs.pop('loop', None))
- kwargs.setdefault('close_fds', _close_fds_default)
- if _asyncio_enabled and isinstance(loop._asyncio_wrapper, _AsyncioEventLoop):
+ # Python 3.4 and later implement PEP 446, which makes newly
+ # created file descriptors non-inheritable by default.
+ kwargs.setdefault('close_fds', False)
+ if isinstance(loop._asyncio_wrapper, _AsyncioEventLoop):
# Use the real asyncio create_subprocess_exec (loop argument
# is deprecated since since Python 3.8).
return _real_asyncio.create_subprocess_exec(*args, **kwargs)
@@ -163,7 +158,7 @@ def iscoroutinefunction(func):
"""
if _compat_coroutine._iscoroutinefunction(func):
return True
- elif _real_asyncio is not None and _real_asyncio.iscoroutinefunction(func):
+ if _real_asyncio.iscoroutinefunction(func):
return True
return False
@@ -191,7 +186,7 @@ def ensure_future(coro_or_future, loop=None):
@return: an instance of Future
"""
loop = _wrap_loop(loop)
- if _asyncio_enabled and isinstance(loop._asyncio_wrapper, _AsyncioEventLoop):
+ if isinstance(loop._asyncio_wrapper, _AsyncioEventLoop):
# Use the real asyncio loop and ensure_future.
return _real_asyncio.ensure_future(
coro_or_future, loop=loop._asyncio_wrapper._loop)
@@ -240,18 +235,12 @@ def _wrap_loop(loop=None):
@rtype: asyncio.AbstractEventLoop (or compatible)
@return: event loop
"""
- return loop or _global_event_loop()
-
-
-if _asyncio_enabled:
# The default loop returned by _wrap_loop should be consistent
# with global_event_loop, in order to avoid accidental registration
# of callbacks with a loop that is not intended to run.
-
- def _wrap_loop(loop=None):
- loop = loop or _global_event_loop()
- return (loop if hasattr(loop, '_asyncio_wrapper')
- else _AsyncioEventLoop(loop=loop))
+ loop = loop or _global_event_loop()
+ return (loop if hasattr(loop, '_asyncio_wrapper')
+ else _AsyncioEventLoop(loop=loop))
def _safe_loop():
@@ -267,5 +256,4 @@ def _safe_loop():
"""
if portage._internal_caller:
return _global_event_loop()
- else:
- return _EventLoop(main=False)
+ return _EventLoop(main=False)
diff --git a/lib/portage/util/futures/_asyncio/process.py b/lib/portage/util/futures/_asyncio/process.py
index 020164c9b..6ff156c9d 100644
--- a/lib/portage/util/futures/_asyncio/process.py
+++ b/lib/portage/util/futures/_asyncio/process.py
@@ -1,15 +1,18 @@
-# Copyright 2018 Gentoo Foundation
+# Copyright 2018-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
+import os
+
import portage
portage.proxy.lazyimport.lazyimport(globals(),
'portage.util.futures:asyncio',
+ 'portage.util.futures.unix_events:_set_nonblocking',
)
from portage.util.futures._asyncio.streams import _reader, _writer
from portage.util.futures.compat_coroutine import coroutine, coroutine_return
-class _Process(object):
+class _Process:
"""
Emulate a subset of the asyncio.subprocess.Process interface,
for python2.
@@ -36,7 +39,7 @@ class _Process(object):
return self._proc.returncode
@coroutine
- def communicate(self, input=None):
+ def communicate(self, input=None): # pylint: disable=redefined-builtin
"""
Read data from stdout and stderr, until end-of-file is reached.
Wait for process to terminate.
@@ -59,7 +62,11 @@ class _Process(object):
if input is not None:
if self._proc.stdin is None:
raise TypeError('communicate: expected file or int, got {}'.format(type(self._proc.stdin)))
- writer = asyncio.ensure_future(_writer(self._proc.stdin, input), loop=self._loop)
+ stdin = self._proc.stdin
+ stdin = os.fdopen(stdin, 'wb', 0) if isinstance(stdin, int) else stdin
+ _set_nonblocking(stdin.fileno())
+ writer = asyncio.ensure_future(_writer(stdin, input, loop=self._loop), loop=self._loop)
+ writer.add_done_callback(lambda writer: stdin.close())
try:
yield asyncio.wait(futures + [self.wait()], loop=self._loop)
diff --git a/lib/portage/util/futures/_asyncio/streams.py b/lib/portage/util/futures/_asyncio/streams.py
index 650a16491..ea5882dd3 100644
--- a/lib/portage/util/futures/_asyncio/streams.py
+++ b/lib/portage/util/futures/_asyncio/streams.py
@@ -1,4 +1,4 @@
-# Copyright 2018 Gentoo Foundation
+# Copyright 2018-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import errno
@@ -8,7 +8,6 @@ import portage
portage.proxy.lazyimport.lazyimport(globals(),
'_emerge.PipeReader:PipeReader',
'portage.util.futures:asyncio',
- 'portage.util.futures.unix_events:_set_nonblocking',
)
from portage.util.futures.compat_coroutine import coroutine
@@ -31,7 +30,7 @@ def _reader(input_file, loop=None):
return future
-class _Reader(object):
+class _Reader:
def __init__(self, future, input_file, loop):
self._future = future
self._pipe_reader = PipeReader(
@@ -59,38 +58,37 @@ class _Reader(object):
@coroutine
def _writer(output_file, content, loop=None):
"""
- Asynchronously write bytes to output file, and close it when
- done. If an EnvironmentError other than EAGAIN is encountered,
- which typically indicates that the other end of the pipe has
- close, the error is raised. This function is a coroutine.
+ Asynchronously write bytes to output file. The output file is
+ assumed to be in non-blocking mode. If an EnvironmentError
+ other than EAGAIN is encountered, which typically indicates that
+ the other end of the pipe has closed, the error is raised.
+ This function is a coroutine.
- @param output_file: output file descriptor
- @type output_file: file or int
+ @param output_file: output file
+ @type output_file: file object
@param content: content to write
@type content: bytes
@param loop: asyncio.AbstractEventLoop (or compatible)
@type loop: event loop
"""
- fd = output_file if isinstance(output_file, int) else output_file.fileno()
- _set_nonblocking(fd)
loop = asyncio._wrap_loop(loop)
- try:
- while content:
+ fd = output_file.fileno()
+ while content:
+ try:
+ content = content[os.write(fd, content):]
+ except EnvironmentError as e:
+ if e.errno != errno.EAGAIN:
+ raise
waiter = loop.create_future()
- loop.add_writer(fd, lambda: waiter.set_result(None))
+ loop.add_writer(fd, lambda: waiter.done() or waiter.set_result(None))
try:
yield waiter
- while content:
- try:
- content = content[os.write(fd, content):]
- except EnvironmentError as e:
- if e.errno == errno.EAGAIN:
- break
- else:
- raise
finally:
- loop.remove_writer(fd)
- except GeneratorExit:
- raise
- finally:
- os.close(output_file) if isinstance(output_file, int) else output_file.close()
+ # The loop and output file may have been closed.
+ if not loop.is_closed():
+ waiter.done() or waiter.cancel()
+ # Do not call remove_writer in cases where fd has
+ # been closed and then re-allocated to a concurrent
+ # coroutine as in bug 716636.
+ if not output_file.closed:
+ loop.remove_writer(fd)
diff --git a/lib/portage/util/futures/_asyncio/tasks.py b/lib/portage/util/futures/_asyncio/tasks.py
index b20765b7a..84c6f4462 100644
--- a/lib/portage/util/futures/_asyncio/tasks.py
+++ b/lib/portage/util/futures/_asyncio/tasks.py
@@ -8,12 +8,7 @@ ___all___ = (
'wait',
)
-try:
- from asyncio import ALL_COMPLETED, FIRST_COMPLETED, FIRST_EXCEPTION
-except ImportError:
- ALL_COMPLETED = 'ALL_COMPLETED'
- FIRST_COMPLETED ='FIRST_COMPLETED'
- FIRST_EXCEPTION = 'FIRST_EXCEPTION'
+from asyncio import ALL_COMPLETED, FIRST_COMPLETED, FIRST_EXCEPTION
import portage
portage.proxy.lazyimport.lazyimport(globals(),
@@ -49,7 +44,7 @@ def wait(futures, loop=None, timeout=None, return_when=ALL_COMPLETED):
return result_future
-class _Waiter(object):
+class _Waiter:
def __init__(self, futures, timeout, return_when, result_future, loop):
self._futures = futures
self._completed = set()
diff --git a/lib/portage/util/futures/compat_coroutine.py b/lib/portage/util/futures/compat_coroutine.py
index 54fc316fe..79bd0da68 100644
--- a/lib/portage/util/futures/compat_coroutine.py
+++ b/lib/portage/util/futures/compat_coroutine.py
@@ -78,7 +78,7 @@ class _CoroutineReturnValue(Exception):
self.result = result
-class _GeneratorTask(object):
+class _GeneratorTask:
"""
Asynchronously executes the generator to completion, waiting for
the result of each Future that it yields, and sending the result
@@ -134,4 +134,3 @@ class _GeneratorTask(object):
else:
self._current_task = asyncio.ensure_future(future, loop=self._loop)
self._current_task.add_done_callback(self._next)
-
diff --git a/lib/portage/util/futures/events.py b/lib/portage/util/futures/events.py
index b772bc242..85032fcdf 100644
--- a/lib/portage/util/futures/events.py
+++ b/lib/portage/util/futures/events.py
@@ -9,33 +9,29 @@ __all__ = (
import socket
import subprocess
-try:
- from asyncio.events import (
- AbstractEventLoop as _AbstractEventLoop,
- AbstractEventLoopPolicy as _AbstractEventLoopPolicy,
- )
-except ImportError:
- _AbstractEventLoop = object
- _AbstractEventLoopPolicy = object
+from asyncio.events import (
+ AbstractEventLoop as _AbstractEventLoop,
+ AbstractEventLoopPolicy as _AbstractEventLoopPolicy,
+)
class AbstractEventLoopPolicy(_AbstractEventLoopPolicy):
- """Abstract policy for accessing the event loop."""
+ """Abstract policy for accessing the event loop."""
- def get_event_loop(self):
- raise NotImplementedError
+ def get_event_loop(self):
+ raise NotImplementedError
- def set_event_loop(self, loop):
- raise NotImplementedError
+ def set_event_loop(self, loop):
+ raise NotImplementedError
- def new_event_loop(self):
- raise NotImplementedError
+ def new_event_loop(self):
+ raise NotImplementedError
- def get_child_watcher(self):
- raise NotImplementedError
+ def get_child_watcher(self):
+ raise NotImplementedError
- def set_child_watcher(self, watcher):
- raise NotImplementedError
+ def set_child_watcher(self, watcher):
+ raise NotImplementedError
class AbstractEventLoop(_AbstractEventLoop):
@@ -92,7 +88,7 @@ class AbstractEventLoop(_AbstractEventLoop):
def set_default_executor(self, executor):
raise NotImplementedError
- def getaddrinfo(self, host, port, family=0, type=0, proto=0, flags=0):
+ def getaddrinfo(self, host, port, family=0, type=0, proto=0, flags=0): # pylint: disable=redefined-builtin
raise NotImplementedError
def getnameinfo(self, sockaddr, flags=0):
@@ -188,4 +184,3 @@ class AbstractEventLoop(_AbstractEventLoop):
def set_debug(self, enabled):
raise NotImplementedError
-
diff --git a/lib/portage/util/futures/executor/fork.py b/lib/portage/util/futures/executor/fork.py
index add7b3c9e..2cf713e9b 100644
--- a/lib/portage/util/futures/executor/fork.py
+++ b/lib/portage/util/futures/executor/fork.py
@@ -16,7 +16,7 @@ from portage.util.futures import asyncio
from portage.util.cpuinfo import get_cpu_count
-class ForkExecutor(object):
+class ForkExecutor:
"""
An implementation of concurrent.futures.Executor that forks a
new process for each task, with support for cancellation of tasks.
diff --git a/lib/portage/util/futures/extendedfutures.py b/lib/portage/util/futures/extendedfutures.py
index af384c745..158048a34 100644
--- a/lib/portage/util/futures/extendedfutures.py
+++ b/lib/portage/util/futures/extendedfutures.py
@@ -4,8 +4,6 @@
# This module provides an extended subset of the asyncio.futures.Futures
# interface.
-from __future__ import unicode_literals
-
__all__ = (
'CancelledError',
'ExtendedFuture',
diff --git a/lib/portage/util/futures/futures.py b/lib/portage/util/futures/futures.py
index 9c9900d4c..839c767a7 100644
--- a/lib/portage/util/futures/futures.py
+++ b/lib/portage/util/futures/futures.py
@@ -5,8 +5,6 @@
# asyncio module (Python 3.3 and earlier), this module provides a
# subset of the asyncio.futures.Futures interface.
-from __future__ import unicode_literals
-
__all__ = (
'CancelledError',
'Future',
@@ -14,32 +12,14 @@ __all__ = (
'TimeoutError',
)
-try:
- from asyncio import (
- CancelledError,
- Future,
- InvalidStateError,
- TimeoutError,
- )
-except ImportError:
-
- from portage.exception import PortageException
-
- class Error(PortageException):
- pass
-
- class CancelledError(Error):
- def __init__(self):
- Error.__init__(self, "cancelled")
-
- class TimeoutError(Error):
- def __init__(self):
- Error.__init__(self, "timed out")
-
- class InvalidStateError(Error):
- pass
-
- Future = None
+# pylint: disable=redefined-builtin
+from asyncio import (
+ CancelledError,
+ Future,
+ InvalidStateError,
+ TimeoutError,
+)
+# pylint: enable=redefined-builtin
import portage
portage.proxy.lazyimport.lazyimport(globals(),
@@ -50,7 +30,7 @@ _PENDING = 'PENDING'
_CANCELLED = 'CANCELLED'
_FINISHED = 'FINISHED'
-class _EventLoopFuture(object):
+class _EventLoopFuture:
"""
This class provides (a subset of) the asyncio.Future interface, for
use with the EventLoop class, because EventLoop is currently
@@ -193,7 +173,3 @@ class _EventLoopFuture(object):
self._exception = exception
self._state = _FINISHED
self._schedule_callbacks()
-
-
-if Future is None:
- Future = _EventLoopFuture
diff --git a/lib/portage/util/futures/retry.py b/lib/portage/util/futures/retry.py
index ccfc087ab..4092f60d6 100644
--- a/lib/portage/util/futures/retry.py
+++ b/lib/portage/util/futures/retry.py
@@ -73,7 +73,7 @@ def _retry(loop, try_max, try_timeout, overall_timeout, delay_func,
return future
-class _Retry(object):
+class _Retry:
def __init__(self, future, loop, try_max, try_timeout, overall_timeout,
delay_func, reraise, func):
self._future = future
diff --git a/lib/portage/util/futures/transports.py b/lib/portage/util/futures/transports.py
index 60ea93073..016ecbef8 100644
--- a/lib/portage/util/futures/transports.py
+++ b/lib/portage/util/futures/transports.py
@@ -1,10 +1,7 @@
# Copyright 2018 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-try:
- from asyncio.transports import Transport as _Transport
-except ImportError:
- _Transport = object
+from asyncio.transports import Transport as _Transport
class _FlowControlMixin(_Transport):
diff --git a/lib/portage/util/futures/unix_events.py b/lib/portage/util/futures/unix_events.py
index 3381eaa7d..16a9e12b7 100644
--- a/lib/portage/util/futures/unix_events.py
+++ b/lib/portage/util/futures/unix_events.py
@@ -6,20 +6,13 @@ __all__ = (
'DefaultEventLoopPolicy',
)
-try:
- import asyncio as _real_asyncio
- from asyncio.base_subprocess import BaseSubprocessTransport as _BaseSubprocessTransport
- from asyncio.unix_events import AbstractChildWatcher as _AbstractChildWatcher
- from asyncio.transports import (
- ReadTransport as _ReadTransport,
- WriteTransport as _WriteTransport,
- )
-except ImportError:
- _real_asyncio = None
- _AbstractChildWatcher = object
- _BaseSubprocessTransport = object
- _ReadTransport = object
- _WriteTransport = object
+import asyncio as _real_asyncio
+from asyncio.base_subprocess import BaseSubprocessTransport as _BaseSubprocessTransport
+from asyncio.unix_events import AbstractChildWatcher as _AbstractChildWatcher
+from asyncio.transports import (
+ ReadTransport as _ReadTransport,
+ WriteTransport as _WriteTransport,
+)
import errno
import fcntl
@@ -32,7 +25,6 @@ import subprocess
import sys
from portage.util._eventloop.global_event_loop import (
- _asyncio_enabled,
global_event_loop as _global_event_loop,
)
from portage.util.futures import (
@@ -441,7 +433,7 @@ class _UnixWritePipeTransport(_FlowControlMixin, _WriteTransport):
return
if n == len(data):
return
- elif n > 0:
+ if n > 0:
data = memoryview(data)[n:]
self._loop.add_writer(self._fileno, self._write_ready)
@@ -471,7 +463,7 @@ class _UnixWritePipeTransport(_FlowControlMixin, _WriteTransport):
self._loop.remove_reader(self._fileno)
self._call_connection_lost(None)
return
- elif n > 0:
+ if n > 0:
del self._buffer[:n]
def can_write_eof(self):
@@ -625,10 +617,9 @@ class _PortageChildWatcher(_AbstractChildWatcher):
def _compute_returncode(self, status):
if os.WIFSIGNALED(status):
return -os.WTERMSIG(status)
- elif os.WIFEXITED(status):
+ if os.WIFEXITED(status):
return os.WEXITSTATUS(status)
- else:
- return status
+ return status
def add_child_handler(self, pid, callback, *args):
"""
@@ -701,5 +692,4 @@ class _AsyncioEventLoopPolicy(_PortageEventLoopPolicy):
return super(_AsyncioEventLoopPolicy, self).get_child_watcher()
-DefaultEventLoopPolicy = (_AsyncioEventLoopPolicy if _asyncio_enabled
- else _PortageEventLoopPolicy)
+DefaultEventLoopPolicy = _AsyncioEventLoopPolicy
diff --git a/lib/portage/util/install_mask.py b/lib/portage/util/install_mask.py
index 0013effa1..9442128bd 100644
--- a/lib/portage/util/install_mask.py
+++ b/lib/portage/util/install_mask.py
@@ -1,4 +1,4 @@
-# Copyright 2018-2019 Gentoo Authors
+# Copyright 2018-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
__all__ = ['install_mask_dir', 'InstallMask']
@@ -6,9 +6,7 @@ __all__ = ['install_mask_dir', 'InstallMask']
import collections
import errno
import fnmatch
-import functools
import operator
-import sys
from portage import os, _unicode_decode
from portage.exception import (
@@ -20,11 +18,6 @@ from portage.exception import (
)
from portage.util import normalize_path
-if sys.hexversion >= 0x3000000:
- _unicode = str
-else:
- _unicode = unicode
-
def _defaultdict_tree():
return collections.defaultdict(_defaultdict_tree)
@@ -38,7 +31,7 @@ _pattern = collections.namedtuple('_pattern', (
))
-class InstallMask(object):
+class InstallMask:
def __init__(self, install_mask):
"""
@param install_mask: INSTALL_MASK value
@@ -152,7 +145,7 @@ def _raise_exc(e):
wrapper_cls = _exc_map.get(e.errno)
if wrapper_cls is None:
raise
- wrapper = wrapper_cls(_unicode(e))
+ wrapper = wrapper_cls(str(e))
wrapper.__cause__ = e
raise wrapper
diff --git a/lib/portage/util/iterators/MultiIterGroupBy.py b/lib/portage/util/iterators/MultiIterGroupBy.py
index 2c31f269f..18f48a016 100644
--- a/lib/portage/util/iterators/MultiIterGroupBy.py
+++ b/lib/portage/util/iterators/MultiIterGroupBy.py
@@ -3,7 +3,7 @@
import bisect
-class MultiIterGroupBy(object):
+class MultiIterGroupBy:
"""
This class functions similarly to the itertools.groupby function,
except that it takes multiple source iterators as input. The source
@@ -78,7 +78,7 @@ class MultiIterGroupBy(object):
for k in yield_these:
yield key_map.pop(k)
-class _IteratorTracker(object):
+class _IteratorTracker:
__slots__ = ('current', 'iterator')
diff --git a/lib/portage/util/lafilefixer.py b/lib/portage/util/lafilefixer.py
index 110010363..482762bf7 100644
--- a/lib/portage/util/lafilefixer.py
+++ b/lib/portage/util/lafilefixer.py
@@ -109,18 +109,18 @@ def rewrite_lafile(contents):
#Two cases:
#1) /usr/lib64/libfoo.la, turn it into -lfoo and append -L/usr/lib64 to libladir
#2) libfoo.la, keep it
- dir, file = _os.path.split(dep_libs_entry)
+ dirname, basename = _os.path.split(dep_libs_entry)
- if not dir or not file.startswith(b"lib"):
+ if not dirname or not basename.startswith(b"lib"):
if dep_libs_entry not in new_dep_libs:
new_dep_libs.append(dep_libs_entry)
else:
#/usr/lib64/libfoo.la -> -lfoo
- lib = b"-l" + file[3:-3]
+ lib = b"-l" + basename[3:-3]
if lib not in new_dep_libs:
new_dep_libs.append(lib)
#/usr/lib64/libfoo.la -> -L/usr/lib64
- ladir = b"-L" + dir
+ ladir = b"-L" + dirname
if ladir not in libladir:
libladir.append(ladir)
@@ -181,5 +181,4 @@ def rewrite_lafile(contents):
if changed:
return True, contents
- else:
- return False, None
+ return False, None
diff --git a/lib/portage/util/listdir.py b/lib/portage/util/listdir.py
index 2012e145f..e6fb9c06d 100644
--- a/lib/portage/util/listdir.py
+++ b/lib/portage/util/listdir.py
@@ -5,10 +5,7 @@ __all__ = ['cacheddir', 'listdir']
import errno
import stat
-import sys
-if sys.hexversion < 0x3000000:
- from itertools import izip as zip
from portage import os
from portage.const import VCS_DIRS
diff --git a/lib/portage/util/locale.py b/lib/portage/util/locale.py
index 5b09945d6..f7e99a4fd 100644
--- a/lib/portage/util/locale.py
+++ b/lib/portage/util/locale.py
@@ -6,7 +6,7 @@ Function to check whether the current used LC_CTYPE handles case
transformations of ASCII characters in a way compatible with the POSIX
locale.
"""
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
import locale
import logging
diff --git a/lib/portage/util/monotonic.py b/lib/portage/util/monotonic.py
deleted file mode 100644
index e50564851..000000000
--- a/lib/portage/util/monotonic.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2018 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-__all__ = ['monotonic']
-
-import time
-try:
- import threading
-except ImportError:
- import dummy_threading as threading
-
-monotonic = getattr(time, 'monotonic', None)
-
-if monotonic is None:
- def monotonic():
- """
- Emulate time.monotonic() which is available in Python 3.3 and later.
-
- @return: A float expressed in seconds since an epoch.
- """
- with monotonic._lock:
- current = time.time() + monotonic._offset
- delta = current - monotonic._previous
- if delta < 0:
- monotonic._offset -= delta
- current = monotonic._previous
- else:
- monotonic._previous = current
- return current
-
- # offset is used to counteract any backward movements
- monotonic._offset = 0
- monotonic._previous = time.time()
- monotonic._lock = threading.Lock()
diff --git a/lib/portage/util/movefile.py b/lib/portage/util/movefile.py
index 5477a669f..3a17d5240 100644
--- a/lib/portage/util/movefile.py
+++ b/lib/portage/util/movefile.py
@@ -1,7 +1,7 @@
-# Copyright 2010-2018 Gentoo Foundation
+# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import
__all__ = ['movefile']
@@ -9,7 +9,6 @@ import errno
import fnmatch
import os as _os
import stat
-import sys
import textwrap
import portage
@@ -41,7 +40,7 @@ def _get_xattr_excluder(pattern):
return value
-class _xattr_excluder(object):
+class _xattr_excluder:
__slots__ = ('_pattern_split',)
@@ -188,18 +187,13 @@ def movefile(src, dest, newmtime=None, sstat=None, mysettings=None,
except OSError:
pass
- if sys.hexversion >= 0x3030000:
- try:
- os.utime(dest, ns=(sstat.st_mtime_ns, sstat.st_mtime_ns), follow_symlinks=False)
- except NotImplementedError:
- # utimensat() and lutimes() missing in libc.
- return os.stat(dest, follow_symlinks=False).st_mtime_ns
- else:
- return sstat.st_mtime_ns
+ try:
+ os.utime(dest, ns=(sstat.st_mtime_ns, sstat.st_mtime_ns), follow_symlinks=False)
+ except NotImplementedError:
+ # utimensat() and lutimes() missing in libc.
+ return os.stat(dest, follow_symlinks=False).st_mtime_ns
else:
- # utime() in Python <3.3 only works on the target of a symlink, so it's not
- # possible to preserve mtime on symlinks.
- return os.lstat(dest)[stat.ST_MTIME]
+ return sstat.st_mtime_ns
except SystemExit as e:
raise
except Exception as e:
@@ -312,49 +306,26 @@ def movefile(src, dest, newmtime=None, sstat=None, mysettings=None,
# if the nanosecond part of the timestamp is 999999881 ns or greater.
try:
if hardlinked:
- if sys.hexversion >= 0x3030000:
- newmtime = os.stat(dest).st_mtime_ns
- else:
- newmtime = os.stat(dest)[stat.ST_MTIME]
+ newmtime = os.stat(dest).st_mtime_ns
else:
# Note: It is not possible to preserve nanosecond precision
# (supported in POSIX.1-2008 via utimensat) with the IEEE 754
# double precision float which only has a 53 bit significand.
if newmtime is not None:
- if sys.hexversion >= 0x3030000:
- os.utime(dest, ns=(newmtime, newmtime))
- else:
- os.utime(dest, (newmtime, newmtime))
+ os.utime(dest, ns=(newmtime, newmtime))
else:
- if sys.hexversion >= 0x3030000:
- newmtime = sstat.st_mtime_ns
- else:
- newmtime = sstat[stat.ST_MTIME]
+ newmtime = sstat.st_mtime_ns
if renamefailed:
- if sys.hexversion >= 0x3030000:
- # If rename succeeded then timestamps are automatically
- # preserved with complete precision because the source
- # and destination inodes are the same. Otherwise, manually
- # update timestamps with nanosecond precision.
- os.utime(dest, ns=(newmtime, newmtime))
- else:
- # If rename succeeded then timestamps are automatically
- # preserved with complete precision because the source
- # and destination inodes are the same. Otherwise, round
- # down to the nearest whole second since python's float
- # st_mtime cannot be used to preserve the st_mtim.tv_nsec
- # field with complete precision. Note that we have to use
- # stat_obj[stat.ST_MTIME] here because the float
- # stat_obj.st_mtime rounds *up* sometimes.
- os.utime(dest, (newmtime, newmtime))
+ # If rename succeeded then timestamps are automatically
+ # preserved with complete precision because the source
+ # and destination inodes are the same. Otherwise, manually
+ # update timestamps with nanosecond precision.
+ os.utime(dest, ns=(newmtime, newmtime))
except OSError:
# The utime can fail here with EPERM even though the move succeeded.
# Instead of failing, use stat to return the mtime if possible.
try:
- if sys.hexversion >= 0x3030000:
- newmtime = os.stat(dest).st_mtime_ns
- else:
- newmtime = os.stat(dest)[stat.ST_MTIME]
+ newmtime = os.stat(dest).st_mtime_ns
except OSError as e:
writemsg(_("!!! Failed to stat in movefile()\n"), noiselevel=-1)
writemsg("!!! %s\n" % dest, noiselevel=-1)
diff --git a/lib/portage/util/mtimedb.py b/lib/portage/util/mtimedb.py
index 30922a901..b8ceeff8e 100644
--- a/lib/portage/util/mtimedb.py
+++ b/lib/portage/util/mtimedb.py
@@ -1,4 +1,4 @@
-# Copyright 2010-2012 Gentoo Foundation
+# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
__all__ = ['MtimeDB']
@@ -12,7 +12,6 @@ except ImportError:
import errno
import io
import json
-import sys
import portage
from portage import _encodings
@@ -32,9 +31,6 @@ class MtimeDB(dict):
"indent": "\t",
"sort_keys": True
}
- if sys.hexversion < 0x30200F0:
- # indent only supports int number of spaces
- _json_write_opts["indent"] = 4
def __init__(self, filename):
dict.__init__(self)
diff --git a/lib/portage/util/socks5.py b/lib/portage/util/socks5.py
index 86bb24f25..c0657ae2a 100644
--- a/lib/portage/util/socks5.py
+++ b/lib/portage/util/socks5.py
@@ -15,7 +15,7 @@ from portage.util.futures.compat_coroutine import coroutine
from portage.util.futures import asyncio
-class ProxyManager(object):
+class ProxyManager:
"""
A class to start and control a single running SOCKSv5 server process
for Portage.
diff --git a/lib/portage/util/whirlpool.py b/lib/portage/util/whirlpool.py
index 170ae73f8..1071d5155 100644
--- a/lib/portage/util/whirlpool.py
+++ b/lib/portage/util/whirlpool.py
@@ -25,9 +25,7 @@
##
## This Python implementation is therefore also placed in the public domain.
-import sys
-if sys.hexversion >= 0x3000000:
- xrange = range
+# pylint: disable=mixed-indentation
#block_size = 64
digest_size = 64
@@ -641,8 +639,6 @@ def WhirlpoolInit(ctx):
def WhirlpoolAdd(source, sourceBits, ctx):
if not isinstance(source, bytes):
raise TypeError("Expected %s, got %s" % (bytes, type(source)))
- if sys.hexversion < 0x3000000:
- source = [ord(s)&0xff for s in source]
carry = 0
value = sourceBits
@@ -700,19 +696,19 @@ def WhirlpoolFinalize(ctx):
bufferPos += 1
if bufferPos > 32:
if bufferPos < 64:
- for i in xrange(64 - bufferPos):
+ for i in range(64 - bufferPos):
ctx.buffer[bufferPos+i] = 0
processBuffer(ctx)
bufferPos = 0
if bufferPos < 32:
- for i in xrange(32 - bufferPos):
+ for i in range(32 - bufferPos):
ctx.buffer[bufferPos+i] = 0
bufferPos = 32
- for i in xrange(32):
+ for i in range(32):
ctx.buffer[32+i] = ctx.bitLength[i]
processBuffer(ctx)
digest = ''
- for i in xrange(8):
+ for i in range(8):
digest += chr((ctx.hash[i] >> 56) % 0x100)
digest += chr((ctx.hash[i] >> 48) % 0x100)
digest += chr((ctx.hash[i] >> 40) % 0x100)
@@ -743,7 +739,7 @@ def processBuffer(ctx):
buffr = ctx.buffer
buf_cnt = 0
- for i in xrange(8):
+ for i in range(8):
block[i] = ((buffr[buf_cnt+0] & 0xff) << 56) ^ \
((buffr[buf_cnt+1] & 0xff) << 48) ^ \
((buffr[buf_cnt+2] & 0xff) << 40) ^ \
@@ -753,11 +749,11 @@ def processBuffer(ctx):
((buffr[buf_cnt+6] & 0xff) << 8) ^ \
((buffr[buf_cnt+7] & 0xff) << 0)
buf_cnt += 8
- for i in xrange(8):
+ for i in range(8):
K[i] = ctx.hash[i]
state[i] = block[i] ^ K[i]
- for r in xrange(1, R+1):
+ for r in range(1, R+1):
L[0] = CDo(K, 0, 7, 6, 5, 4, 3, 2, 1) ^ rc[r]
L[1] = CDo(K, 1, 0, 7, 6, 5, 4, 3, 2)
L[2] = CDo(K, 2, 1, 0, 7, 6, 5, 4, 3)
@@ -766,7 +762,7 @@ def processBuffer(ctx):
L[5] = CDo(K, 5, 4, 3, 2, 1, 0, 7, 6)
L[6] = CDo(K, 6, 5, 4, 3, 2, 1, 0, 7)
L[7] = CDo(K, 7, 6, 5, 4, 3, 2, 1, 0)
- for i in xrange(8):
+ for i in range(8):
K[i] = L[i]
L[0] = CDo(state, 0, 7, 6, 5, 4, 3, 2, 1) ^ K[0]
L[1] = CDo(state, 1, 0, 7, 6, 5, 4, 3, 2) ^ K[1]
@@ -776,10 +772,10 @@ def processBuffer(ctx):
L[5] = CDo(state, 5, 4, 3, 2, 1, 0, 7, 6) ^ K[5]
L[6] = CDo(state, 6, 5, 4, 3, 2, 1, 0, 7) ^ K[6]
L[7] = CDo(state, 7, 6, 5, 4, 3, 2, 1, 0) ^ K[7]
- for i in xrange(8):
+ for i in range(8):
state[i] = L[i]
# apply the Miyaguchi-Preneel compression function
- for i in xrange(8):
+ for i in range(8):
ctx.hash[i] ^= state[i] ^ block[i]
return
diff --git a/lib/portage/util/writeable_check.py b/lib/portage/util/writeable_check.py
index e5b14c023..e3c946e8e 100644
--- a/lib/portage/util/writeable_check.py
+++ b/lib/portage/util/writeable_check.py
@@ -9,8 +9,6 @@ accepts a list of directories and returns a list of mounts which need to be
remounted RW, then add "elif ostype == (the ostype value for your OS)" to
get_ro_checker().
"""
-from __future__ import unicode_literals
-
import io
import logging
import os
diff --git a/lib/portage/versions.py b/lib/portage/versions.py
index 0b1d50e7c..d4ab9d199 100644
--- a/lib/portage/versions.py
+++ b/lib/portage/versions.py
@@ -2,8 +2,6 @@
# Copyright 1998-2016 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import unicode_literals
-
__all__ = [
'best', 'catpkgsplit', 'catsplit',
'cpv_getkey', 'cpv_getversion', 'cpv_sort_key', 'pkgcmp', 'pkgsplit',
@@ -11,14 +9,9 @@ __all__ = [
]
import re
-import sys
import warnings
+from functools import lru_cache
-if sys.hexversion < 0x3000000:
- _unicode = unicode
-else:
- _unicode = str
- long = int
import portage
portage.proxy.lazyimport.lazyimport(globals(),
@@ -113,11 +106,11 @@ def _get_pv_re(eapi_attrs):
def ververify(myver, silent=1):
if ver_regexp.match(myver):
return True
- else:
- if not silent:
- print(_("!!! syntax error in version: %s") % myver)
- return False
+ if not silent:
+ print(_("!!! syntax error in version: %s") % myver)
+ return False
+@lru_cache(1024)
def vercmp(ver1, ver2, silent=1):
"""
Compare two versions
@@ -210,9 +203,9 @@ def vercmp(ver1, ver2, silent=1):
for i in range(0, max(len(list1), len(list2))):
if len(list1) <= i:
return -1
- elif len(list2) <= i:
+ if len(list2) <= i:
return 1
- elif list1[i] != list2[i]:
+ if list1[i] != list2[i]:
a = list1[i]
b = list2[i]
rval = (a > b) - (a < b)
@@ -347,6 +340,7 @@ def _pkgsplit(mypkg, eapi=None):
_cat_re = re.compile('^%s$' % _cat, re.UNICODE)
_missing_cat = 'null'
+@lru_cache(10240)
def catpkgsplit(mydata, silent=1, eapi=None):
"""
Takes a Category/Package-Version-Rev and returns a list of each.
@@ -379,7 +373,7 @@ def catpkgsplit(mydata, silent=1, eapi=None):
retval = (cat, p_split[0], p_split[1], p_split[2])
return retval
-class _pkg_str(_unicode):
+class _pkg_str(str):
"""
This class represents a cpv. It inherits from str (unicode in python2) and
has attributes that cache results for use by functions like catpkgsplit and
@@ -398,15 +392,15 @@ class _pkg_str(_unicode):
def __new__(cls, cpv, metadata=None, settings=None, eapi=None,
repo=None, slot=None, build_time=None, build_id=None,
file_size=None, mtime=None, db=None):
- return _unicode.__new__(cls, cpv)
+ return str.__new__(cls, cpv)
def __init__(self, cpv, metadata=None, settings=None, eapi=None,
repo=None, slot=None, build_time=None, build_id=None,
file_size=None, mtime=None, db=None):
- if not isinstance(cpv, _unicode):
- # Avoid TypeError from _unicode.__init__ with PyPy.
+ if not isinstance(cpv, str):
+ # Avoid TypeError from str.__init__ with PyPy.
cpv = _unicode_decode(cpv)
- _unicode.__init__(cpv)
+ str.__init__(cpv)
if metadata is not None:
self.__dict__['_metadata'] = metadata
slot = metadata.get('SLOT', slot)
@@ -471,7 +465,7 @@ class _pkg_str(_unicode):
def _long(var, default):
if var is not None:
try:
- var = long(var)
+ var = int(var)
except ValueError:
if var:
var = -1
@@ -511,8 +505,7 @@ def pkgsplit(mypkg, silent=1, eapi=None):
cat, pn, ver, rev = catpsplit
if cat is _missing_cat and '/' not in mypkg:
return (pn, ver, rev)
- else:
- return (cat + '/' + pn, ver, rev)
+ return (cat + '/' + pn, ver, rev)
def cpv_getkey(mycpv, eapi=None):
"""Calls catpkgsplit on a cpv and returns only the cp."""
@@ -535,8 +528,7 @@ def cpv_getkey(mycpv, eapi=None):
mylen = len(myslash)
if mylen == 2:
return myslash[0] + "/" + mysplit[0]
- else:
- return mysplit[0]
+ return mysplit[0]
def cpv_getversion(mycpv, eapi=None):
"""Returns the v (including revision) from an cpv."""
diff --git a/lib/portage/xml/metadata.py b/lib/portage/xml/metadata.py
index 64246c828..646edb5b9 100644
--- a/lib/portage/xml/metadata.py
+++ b/lib/portage/xml/metadata.py
@@ -1,4 +1,4 @@
-# Copyright 2010-2019 Gentoo Authors
+# Copyright 2010-2020 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
"""Provides an easy-to-use python interface to Gentoo's metadata.xml file.
@@ -28,11 +28,8 @@
'Thomas Mills Hinkle'
"""
-from __future__ import unicode_literals
-
__all__ = ('MetaDataXML', 'parse_metadata_use')
-import sys
try:
import xml.etree.cElementTree as etree
@@ -55,10 +52,6 @@ import xml.etree.ElementTree
from portage import _encodings, _unicode_encode
from portage.util import cmp_sort_key, unique_everseen
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- basestring = str
-
class _MetadataTreeBuilder(xml.etree.ElementTree.TreeBuilder):
"""
@@ -68,7 +61,7 @@ class _MetadataTreeBuilder(xml.etree.ElementTree.TreeBuilder):
def doctype(self, name, pubid, system):
pass
-class _Maintainer(object):
+class _Maintainer:
"""An object for representing one maintainer.
@type email: str or None
@@ -101,7 +94,7 @@ class _Maintainer(object):
return "<%s %r>" % (self.__class__.__name__, self.email)
-class _Useflag(object):
+class _Useflag:
"""An object for representing one USE flag.
@todo: Is there any way to have a keyword option to leave in
@@ -131,7 +124,7 @@ class _Useflag(object):
return "<%s %r>" % (self.__class__.__name__, self.name)
-class _Upstream(object):
+class _Upstream:
"""An object for representing one package's upstream.
@type maintainers: list
@@ -187,7 +180,7 @@ class _Upstream(object):
return [(e.text, e.get('type')) for e in self.node.findall('remote-id') if e.text]
-class MetaDataXML(object):
+class MetaDataXML:
"""Access metadata.xml"""
def __init__(self, metadata_xml_path, herds):
@@ -479,12 +472,12 @@ def parse_metadata_use(xml_tree):
stack.append(flag)
while stack:
obj = stack.pop()
- if isinstance(obj, basestring):
+ if isinstance(obj, str):
inner_text.append(obj)
continue
- if isinstance(obj.text, basestring):
+ if isinstance(obj.text, str):
inner_text.append(obj.text)
- if isinstance(obj.tail, basestring):
+ if isinstance(obj.tail, str):
stack.append(obj.tail)
stack.extend(reversed(obj))
@@ -494,4 +487,3 @@ def parse_metadata_use(xml_tree):
# (flag_restrict can be None)
uselist[flag.get("name")][flag_restrict] = " ".join("".join(inner_text).split())
return uselist
-
diff --git a/lib/portage/xpak.py b/lib/portage/xpak.py
index c708190b9..3401c5073 100644
--- a/lib/portage/xpak.py
+++ b/lib/portage/xpak.py
@@ -24,7 +24,6 @@ __all__ = [
import array
import errno
-import sys
import portage
from portage import os
@@ -78,8 +77,6 @@ def encodeint(myint):
def decodeint(mystring):
"""Takes a 4 byte string and converts it into a 4 byte integer.
Returns an integer."""
- if sys.hexversion < 0x3000000:
- mystring = [ord(x) for x in mystring]
myint = 0
myint += mystring[3]
myint += mystring[2] << 8
@@ -276,7 +273,7 @@ def xpand(myid, mydest):
mydat.close()
startpos = startpos + namelen + 12
-class tbz2(object):
+class tbz2:
def __init__(self, myfile):
self.file = myfile
self.filestat = None
diff --git a/man/ebuild.5 b/man/ebuild.5
index 4ca3f3a15..476844281 100644
--- a/man/ebuild.5
+++ b/man/ebuild.5
@@ -342,7 +342,7 @@ This variable must NEVER be modified.
\fBExample\fR:
.nf
- x11\-base/xorg\-server\-1.20.5\-r2 \-\-> '\fIx11\-base/xorg\-server\-1.20.5\fR'
+ x11\-base/xorg\-server\-1.20.5\-r2 \-\-> '\fIxorg\-server\-1.20.5\fR'
.fi
.TP
.B PN
@@ -350,7 +350,7 @@ Contains the name of the script without the version number.
\fBExample\fR:
.nf
- x11\-base/xorg\-server\-1.20.5\-r2 \-\-> '\fIx11\-base/xorg\-server\fR'
+ x11\-base/xorg\-server\-1.20.5\-r2 \-\-> '\fIxorg\-server\fR'
.fi
.TP
.B PV
diff --git a/man/egencache.1 b/man/egencache.1
index 27cd69e63..98b230a14 100644
--- a/man/egencache.1
+++ b/man/egencache.1
@@ -13,7 +13,7 @@ itself, for distribution.
.BR "\-\-update [ATOM] ... "
Update the \fImetadata/md5\-cache/\fR directory (generate metadata as
necessary).
-If no package atoms are specified then all will be updated. See ebuild(5)
+If no package atoms are specified then all will be updated. See \fBebuild\fR(5)
for the details on package atom syntax.
.TP
.BR "\-\-update\-changelogs"
@@ -151,7 +151,7 @@ exists in the repository. It can also be explicitly enabled via the
cache\-formats setting in \fImetadata/layout.conf\fR (refer to \fBportage\fR(5)
for example usage). If the 'pms' cache format is enabled and the 'md5-dict'
format is not enabled, then it is necessary to enable
-\fBmetadata-transfer\fR in \fBFEATURES\fR (see \fBmake.conf(5)\fR).
+\fBmetadata-transfer\fR in \fBFEATURES\fR (see \fBmake.conf\fR(5)).
This causes intermediate cache (in a different format that includes
eclass state) to be generated inside the directory which is configurable
via the \fB\-\-cache\-dir\fR option.
diff --git a/man/emerge.1 b/man/emerge.1
index aa28ab337..a2a0c2faa 100644
--- a/man/emerge.1
+++ b/man/emerge.1
@@ -56,8 +56,8 @@ A \fItbz2file\fR must be a valid .tbz2 created with \fBebuild
A \fIfile\fR must be a file or directory that has been installed by one or
more packages. If an absolute path is not used, then it must begin with
either "./" or "../". For directories that are owned by multiple packages, all
-owning packages will be selected. See the portageq(1) owners command if you
-would like to query the owners of one or more files or directories.
+owning packages will be selected. See the \fBportageq\fR(1) owners command if
+you would like to query the owners of one or more files or directories.
.TP
.BR set
A \fIset\fR is a convenient shorthand for a large group of
@@ -1100,7 +1100,7 @@ This also applies to options that enable the \fB\-\-usepkg\fR option
implicitly, such as \fB\-\-getbinpkg\fR.
This setting can be added to
-\fBEMERGE_DEFAULT_OPTS\fR (see make.conf(5)) and later overridden via the
+\fBEMERGE_DEFAULT_OPTS\fR (see \fBmake.conf\fR(5)) and later overridden via the
command line.
.TP
.BR "\-\-with\-bdeps\-auto < y | n >"
@@ -1109,7 +1109,7 @@ This option is used to enable or disable the program logic that causes
actions. This option is enabled by default. Use
\fB\-\-with\-bdeps\-auto=n\fR to prevent \fB\-\-with\-bdeps\fR from
being automatically enabled for installation actions. This setting can
-be added to \fBEMERGE_DEFAULT_OPTS\fR (see make.conf(5)) and later
+be added to \fBEMERGE_DEFAULT_OPTS\fR (see \fBmake.conf\fR(5)) and later
overridden via the command line.
\fBNOTE:\fR The program logic that causes \fB\-\-with\-bdeps\fR to be
diff --git a/man/make.conf.5 b/man/make.conf.5
index ab00cb7d7..d0af57891 100644
--- a/man/make.conf.5
+++ b/man/make.conf.5
@@ -1,4 +1,4 @@
-.TH "MAKE.CONF" "5" "May 2020" "Portage VERSION" "Portage"
+.TH "MAKE.CONF" "5" "Jun 2020" "Portage VERSION" "Portage"
.SH "NAME"
make.conf \- custom settings for Portage
.SH "SYNOPSIS"
@@ -985,6 +985,11 @@ with an integer pid. For example, a value of "ionice \-c 3 \-p \\${PID}"
will set idle io priority. For more information about ionice, see
\fBionice\fR(1). This variable is unset by default.
.TP
+.B PORTAGE_LOG_FILTER_FILE_CMD
+This variable specifies a command that filters build log output to a
+log file. In order to filter ANSI escape codes from build logs,
+\fBansifilter\fR(1) is a convenient setting for this variable.
+.TP
.B PORTAGE_LOGDIR
This variable defines the directory in which per\-ebuild logs are kept.
Logs are created only when this is set. They are stored as
diff --git a/man/portage.5 b/man/portage.5
index 36c871123..a7e64cd5f 100644
--- a/man/portage.5
+++ b/man/portage.5
@@ -1,4 +1,4 @@
-.TH "PORTAGE" "5" "Apr 2019" "Portage VERSION" "Portage"
+.TH "PORTAGE" "5" "Jul 2020" "Portage VERSION" "Portage"
.SH NAME
portage \- the heart of Gentoo
.SH "DESCRIPTION"
@@ -916,13 +916,11 @@ When 'force = aliases' attribute is not set, \fBegencache\fR(1),
since operations performed by these tools are inherently
\fBnot\fR \fIsite\-specific\fR.
.TP
-.B auto\-sync
+.B auto\-sync = yes|no|true|false
This setting determines if the repo will be synced during "\fBemerge \-\-sync\fR" or
"\fBemaint sync \-\-auto\fR" runs. This allows for repositories to be synced only when
desired via "\fBemaint sync \-\-repo foo\fR".
.br
-Valid values: yes, no, true, false.
-.br
If unset, the repo will be treated as set
yes, true.
.TP
@@ -966,20 +964,18 @@ since operations performed by these tools are inherently
.B priority
Specifies priority of given repository.
.TP
-.B strict\-misc\-digests
+.B strict\-misc\-digests = yes|no|true|false
This setting determines whether digests are checked for files declared
in the Manifest with MISC type (includes ChangeLog and metadata.xml
-files). Defaults to true.
-.br
-Valid values: true, false.
+files). Defaults to yes, true.
.TP
-.B sync\-allow\-hardlinks = yes|no
+.B sync\-allow\-hardlinks = yes|no|true|false
Allow sync plugins to use hardlinks in order to ensure that a repository
remains in a valid state if something goes wrong during the sync operation.
For example, if signature verification fails during a sync operation,
the previous state of the repository will be preserved. This option may
conflict with configurations that restrict the use of hardlinks, such as
-overlay filesystems.
+overlay filesystems. Defaults to yes, true.
.TP
.B sync\-cvs\-repo
Specifies CVS repository.
@@ -1016,16 +1012,17 @@ See also example for sync-git-clone-env.
.B sync\-git\-pull\-extra\-opts
Extra options to give to git when updating repository (git pull).
.TP
-.B sync\-git\-verify\-commit\-signature = true|false
+.B sync\-git\-verify\-commit\-signature = yes|no|true|false
Require the top commit in the repository to contain a good OpenPGP
-signature. Defaults to false.
+signature. Defaults to no, false.
.TP
-.B sync\-hooks\-only\-on\-change
+.B sync\-hooks\-only\-on\-change = yes|no|true|false
If set to true, then sync of a given repository will not trigger postsync
hooks unless hooks would have executed for a master repository or the
-repository has changed since the previous sync operation.
+repository has changed since the previous sync operation. Defaults to
+no, false.
.TP
-.B sync\-rcu = yes|no
+.B sync\-rcu = yes|no|true|false
Enable read\-copy\-update (RCU) behavior for sync operations. The current
latest immutable version of a repository will be referenced by a symlink
found where the repository would normally be located (see the \fBlocation\fR
@@ -1125,6 +1122,13 @@ only for protocols supporting cryptographic verification, provided
that the respective verification option is enabled. If unset, the user's
keyring is used.
.TP
+.B sync\-openpgp\-key\-refresh = yes
+Enable OpenPGP key(ring) refresh. This option is enabled by default.
+
+\fBWarning\fR: It is a security vulnerability to disable this option
+because this will prevent detection of revoked keys!
+
+.TP
.B sync\-openpgp\-key\-refresh\-retry\-count = 40
Maximum number of times to retry key refresh if it fails. Between each
key refresh attempt, there is an exponential delay with a constant
@@ -1149,10 +1153,10 @@ Pass \fIname\fR as the `gpg \-\-keyserver` argument. Refer to the
\fBgpg\fR(1) man page for information about the `gpg \-\-keyserver`
\fIname\fR format.
.TP
-.B sync-rsync-vcs-ignore = true|false
+.B sync\-rsync\-vcs\-ignore = yes|no|true|false
Ignore vcs directories that may be present in the repository. It is the
user's responsibility to set sync-rsync-extra-opts to protect vcs
-directories if appropriate.
+directories if appropriate. Defaults to no, false.
.TP
.B sync\-rsync\-verify\-jobs = 1
Number of parallel jobs to use when verifying nested Manifests. When
@@ -1164,21 +1168,21 @@ Defaults to 1.
Warn if repository is older than the specified number of days. Disabled
when 0. Defaults to disabled.
.TP
-.B sync\-rsync\-verify\-metamanifest = yes|no
+.B sync\-rsync\-verify\-metamanifest = yes|no|true|false
Require the repository to contain a signed MetaManifest and verify
-it using \fBapp\-portage/gemato\fR. Defaults to no.
+it using \fBapp\-portage/gemato\fR. Defaults to no, false.
.TP
-.B sync\-webrsync\-delta = true|false
+.B sync\-webrsync\-delta = yes|no|true|false
Use \fBapp\-portage/emerge\-delta\-webrsync\fR to minimize bandwidth.
-Defaults to false.
+Defaults to no, false.
.TP
-.B sync\-webrsync\-keep\-snapshots = true|false
-Keep snapshots in \fBDISTDIR\fR (do not delete). Defaults to false.
+.B sync\-webrsync\-keep\-snapshots = yes|no|true|false
+Keep snapshots in \fBDISTDIR\fR (do not delete). Defaults to no, false.
.TP
-.B sync\-webrsync\-verify\-signature = true|false
+.B sync\-webrsync\-verify\-signature = yes|no|true|false
Require the detached tarball signature to contain a good OpenPGP
signature. This uses the OpenPGP key(ring) specified by the
-sync\-openpgp\-key\-path setting. Defaults to false.
+sync\-openpgp\-key\-path setting. Defaults to no, false.
.RE
diff --git a/pylintrc b/pylintrc
new file mode 100644
index 000000000..19f59c165
--- /dev/null
+++ b/pylintrc
@@ -0,0 +1,464 @@
+[MASTER]
+
+# Disable the message, report, category or checker with the given id(s). You
+# can either give multiple identifiers separated by comma (,) or put this
+# option multiple times (only on the command line, not in the configuration
+# file where it should appear only once). You can also use "--/
+# disable=all" to
+# disable everything first and then reenable specific checks. For example, if
+# you want to run only the similarities checker, you can use "--disable=all
+# --enable=similarities". If you want to run only the classes checker, but have
+# no Warning level messages displayed, use "--disable=all --enable=classes
+# --disable=W".
+#disable=no-absolute-import,bad-continuation,C0103,C0114,C0115,E1101,W0201,no-name-in-module
+disable=all
+enable=redefined-builtin,useless-object-inheritance,trailing-newlines
+
+# A comma-separated list of package or module names from where C extensions may
+# be loaded. Extensions are loading into the active Python interpreter and may
+# run arbitrary code.
+extension-pkg-whitelist=
+
+# Add files or directories to the blacklist. They should be base names, not
+# paths.
+ignore=.git
+
+# Add files or directories matching the regex patterns to the blacklist. The
+# regex matches against base names, not paths.
+ignore-patterns=
+
+# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the
+# number of processors available to use.
+jobs=0
+
+# Control the amount of potential inferred values when inferring a single
+# object. This can help the performance when dealing with large functions or
+# complex, nested conditions.
+limit-inference-results=100
+
+# Pickle collected data for later comparisons.
+persistent=no
+
+# When enabled, pylint would attempt to guess common misconfiguration and emit
+# user-friendly hints instead of false-positive error messages.
+suggestion-mode=yes
+
+# Allow loading of arbitrary C extensions. Extensions are imported into the
+# active Python interpreter and may run arbitrary code.
+unsafe-load-any-extension=no
+
+[MESSAGES CONTROL]
+
+# Only show warnings with the listed confidence levels. Leave empty to show
+# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED.
+confidence=HIGH
+
+[REPORTS]
+
+# Python expression which should return a score less than or equal to 10. You
+# have access to the variables 'error', 'warning', 'refactor', and 'convention'
+# which contain the number of messages in each category, as well as 'statement'
+# which is the total number of statements analyzed. This score is used by the
+# global evaluation report (RP0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+
+# Set the output format. Available formats are text, parseable, colorized, json
+# and msvs (visual studio). You can also give a reporter class, e.g.
+# mypackage.mymodule.MyReporterClass.
+output-format=text
+
+# Tells whether to display a full report or only the messages.
+reports=no
+
+# Activate the evaluation score.
+score=yes
+
+[REFACTORING]
+
+# Maximum number of nested blocks for function / method body
+max-nested-blocks=5
+
+# Complete name of functions that never returns. When checking for
+# inconsistent-return-statements if a never returning function is called then
+# it will be considered as an explicit return statement and no message will be
+# printed.
+never-returning-functions=sys.exit
+
+[BASIC]
+
+# Naming style matching correct argument names.
+argument-naming-style=snake_case
+
+# Naming style matching correct attribute names.
+attr-naming-style=snake_case
+
+# Regular expression matching correct attribute names. Overrides attr-naming-
+# style.
+#attr-rgx=
+
+# Bad variable names which should always be refused, separated by a comma.
+bad-names=
+
+# Naming style matching correct class attribute names.
+class-attribute-naming-style=any
+
+# Naming style matching correct class names.
+class-naming-style=PascalCase
+
+# Naming style matching correct constant names.
+const-naming-style=UPPER_CASE
+
+# Regular expression matching correct constant names. Overrides const-naming-
+# style.
+#const-rgx=
+
+# Minimum line length for functions/classes that require docstrings, shorter
+# ones are exempt.
+docstring-min-length=-1
+
+# Naming style matching correct function names.
+function-naming-style=snake_case
+
+# Regular expression matching correct function names. Overrides function-
+# naming-style.
+#function-rgx=
+
+# Good variable names which should always be accepted, separated by a comma.
+good-names=i,
+ j,
+ k,
+ ex,
+ Run,
+ e,
+ _
+
+# Include a hint for the correct naming format with invalid-name.
+include-naming-hint=no
+
+# Naming style matching correct inline iteration names.
+inlinevar-naming-style=any
+
+# Regular expression matching correct inline iteration names. Overrides
+# inlinevar-naming-style.
+#inlinevar-rgx=
+
+# Naming style matching correct method names.
+method-naming-style=snake_case
+
+# Regular expression matching correct method names. Overrides method-naming-
+# style.
+#method-rgx=
+
+# Naming style matching correct module names.
+module-naming-style=snake_case
+
+# Regular expression matching correct module names. Overrides module-naming-
+# style.
+#module-rgx=
+
+# Colon-delimited sets of names that determine each other's naming style when
+# the name regexes allow several styles.
+name-group=
+
+# Regular expression which should only match function or class names that do
+# not require a docstring.
+no-docstring-rgx=^_
+
+# List of decorators that produce properties, such as abc.abstractproperty. Add
+# to this list to register other decorators that produce valid properties.
+# These decorators are taken in consideration only for invalid-name.
+property-classes=abc.abstractproperty
+
+# Naming style matching correct variable names.
+variable-naming-style=snake_case
+
+# Regular expression matching correct variable names. Overrides variable-
+# naming-style.
+#variable-rgx=
+
+
+[FORMAT]
+
+# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
+expected-line-ending-format=
+
+# Regexp for a line that is allowed to be longer than the limit.
+ignore-long-lines=^\s*(# )?<?https?://\S+>?$
+
+# Number of spaces of indent required inside a hanging or continued line.
+indent-after-paren=4
+
+# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
+# tab).
+indent-string='\t'
+
+# Maximum number of characters on a single line.
+max-line-length=100
+
+# Maximum number of lines in a module.
+max-module-lines=10000
+
+# List of optional constructs for which whitespace checking is disabled. `dict-
+# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
+# `trailing-comma` allows a space between comma and closing bracket: (a, ).
+# `empty-line` allows space-only lines.
+no-space-check=trailing-comma,
+ dict-separator
+
+# Allow the body of a class to be on the same line as the declaration if body
+# contains single statement.
+single-line-class-stmt=no
+
+# Allow the body of an if to be on the same line as the test if there is no
+# else.
+single-line-if-stmt=no
+
+
+[LOGGING]
+
+# Format style used to check logging format string. `old` means using %
+# formatting, `new` is for `{}` formatting,and `fstr` is for f-strings.
+logging-format-style=old
+
+# Logging modules to check that the string format arguments are in logging
+# function parameter format.
+logging-modules=logging
+
+
+[MISCELLANEOUS]
+
+# List of note tags to take in consideration, separated by a comma.
+notes=FIXME,
+ XXX,
+ TODO
+
+
+[SIMILARITIES]
+
+# Ignore comments when computing similarities.
+ignore-comments=yes
+
+# Ignore docstrings when computing similarities.
+ignore-docstrings=yes
+
+# Ignore imports when computing similarities.
+ignore-imports=no
+
+# Minimum lines number of a similarity.
+min-similarity-lines=4
+
+
+[SPELLING]
+
+# Limits count of emitted suggestions for spelling mistakes.
+max-spelling-suggestions=4
+
+# Spelling dictionary name. Available dictionaries: none. To make it work,
+# install the python-enchant package.
+spelling-dict=
+
+# List of comma separated words that should not be checked.
+spelling-ignore-words=
+
+# A path to a file that contains the private dictionary; one word per line.
+spelling-private-dict-file=
+
+# Tells whether to store unknown words to the private dictionary (see the
+# --spelling-private-dict-file option) instead of raising a message.
+spelling-store-unknown-words=no
+
+
+[STRING]
+
+# This flag controls whether the implicit-str-concat-in-sequence should
+# generate a warning on implicit string concatenation in sequences defined over
+# several lines.
+check-str-concat-over-line-jumps=no
+
+
+[TYPECHECK]
+
+# List of decorators that produce context managers, such as
+# contextlib.contextmanager. Add to this list to register other decorators that
+# produce valid context managers.
+contextmanager-decorators=contextlib.contextmanager
+
+# List of members which are set dynamically and missed by pylint inference
+# system, and so shouldn't trigger E1101 when accessed. Python regular
+# expressions are accepted.
+generated-members=
+
+# Tells whether missing members accessed in mixin class should be ignored. A
+# mixin class is detected if its name ends with "mixin" (case insensitive).
+ignore-mixin-members=yes
+
+# Tells whether to warn about missing members when the owner of the attribute
+# is inferred to be None.
+ignore-none=yes
+
+# This flag controls whether pylint should warn about no-member and similar
+# checks whenever an opaque object is returned when inferring. The inference
+# can return multiple potential results while evaluating a Python object, but
+# some branches might not be evaluated, which results in partial inference. In
+# that case, it might be useful to still emit no-member and other checks for
+# the rest of the inferred objects.
+ignore-on-opaque-inference=yes
+
+# List of class names for which member attributes should not be checked (useful
+# for classes with dynamically set attributes). This supports the use of
+# qualified names.
+ignored-classes=optparse.Values,thread._local,_thread._local
+
+# List of module names for which member attributes should not be checked
+# (useful for modules/projects where namespaces are manipulated during runtime
+# and thus existing member attributes cannot be deduced by static analysis). It
+# supports qualified module names, as well as Unix pattern matching.
+ignored-modules=
+
+# Show a hint with possible names when a member name was not found. The aspect
+# of finding the hint is based on edit distance.
+missing-member-hint=yes
+
+# The minimum edit distance a name should have in order to be considered a
+# similar match for a missing member name.
+missing-member-hint-distance=1
+
+# The total number of similar names that should be taken in consideration when
+# showing a hint for a missing member.
+missing-member-max-choices=1
+
+# List of decorators that change the signature of a decorated function.
+signature-mutators=
+
+
+[VARIABLES]
+
+# List of additional names supposed to be defined in builtins. Remember that
+# you should avoid defining new builtins when possible.
+additional-builtins=
+
+# Tells whether unused global variables should be treated as a violation.
+allow-global-unused-variables=yes
+
+# List of strings which can identify a callback function by name. A callback
+# name must start or end with one of those strings.
+callbacks=cb_,
+ _cb
+
+# A regular expression matching the name of dummy variables (i.e. expected to
+# not be used).
+dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
+
+# Argument names that match this expression will be ignored. Default to name
+# with leading underscore.
+ignored-argument-names=_.*|^ignored_|^unused_
+
+# Tells whether we should check for unused import in __init__ files.
+init-import=no
+
+# List of qualified module names which can have objects that can redefine
+# builtins.
+redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io
+
+
+[CLASSES]
+
+# List of method names used to declare (i.e. assign) instance attributes.
+defining-attr-methods=__init__,
+ __new__,
+ setUp,
+ __post_init__
+
+# List of member names, which should be excluded from the protected access
+# warning.
+exclude-protected=_asdict,
+ _fields,
+ _replace,
+ _source,
+ _make
+
+# List of valid names for the first argument in a class method.
+valid-classmethod-first-arg=cls
+
+# List of valid names for the first argument in a metaclass class method.
+valid-metaclass-classmethod-first-arg=cls
+
+
+[DESIGN]
+
+# Maximum number of arguments for function / method.
+max-args=5
+
+# Maximum number of attributes for a class (see R0902).
+max-attributes=7
+
+# Maximum number of boolean expressions in an if statement (see R0916).
+max-bool-expr=5
+
+# Maximum number of branch for function / method body.
+max-branches=12
+
+# Maximum number of locals for function / method body.
+max-locals=15
+
+# Maximum number of parents for a class (see R0901).
+max-parents=7
+
+# Maximum number of public methods for a class (see R0904).
+max-public-methods=20
+
+# Maximum number of return / yield for function / method body.
+max-returns=6
+
+# Maximum number of statements in function / method body.
+max-statements=50
+
+# Minimum number of public methods for a class (see R0903).
+min-public-methods=0
+
+
+[IMPORTS]
+
+# List of modules that can be imported at any level, not just the top level
+# one.
+allow-any-import-level=
+
+# Allow wildcard imports from modules that define __all__.
+allow-wildcard-with-all=no
+
+# Analyse import fallback blocks. This can be used to support both Python 2 and
+# 3 compatible code, which means that the block might have code that exists
+# only in one or another interpreter, leading to false positives when analysed.
+analyse-fallback-blocks=no
+
+# Deprecated modules which should not be used, separated by a comma.
+deprecated-modules=optparse,tkinter.tix
+
+# Create a graph of external dependencies in the given file (report RP0402 must
+# not be disabled).
+ext-import-graph=
+
+# Create a graph of every (i.e. internal and external) dependencies in the
+# given file (report RP0402 must not be disabled).
+import-graph=
+
+# Create a graph of internal dependencies in the given file (report RP0402 must
+# not be disabled).
+int-import-graph=
+
+# Force import order to recognize a module as part of the standard
+# compatibility libraries.
+known-standard-library=
+
+# Force import order to recognize a module as part of a third party library.
+known-third-party=enchant
+
+# Couples of modules and preferred modules, separated by a comma.
+preferred-modules=
+
+
+[EXCEPTIONS]
+
+# Exceptions that will emit a warning when being caught. Defaults to
+# "BaseException, Exception".
+overgeneral-exceptions=BaseException
diff --git a/repoman/RELEASE-NOTES b/repoman/RELEASE-NOTES
index 80541fa5c..0c79956a0 100644
--- a/repoman/RELEASE-NOTES
+++ b/repoman/RELEASE-NOTES
@@ -1,6 +1,11 @@
Release Notes; upgrade information mainly.
Features/major bugfixes are listed in NEWS
+repoman-2.3.23
+==================================
+* Bug Fixes:
+ - Bug 637824 Deprecate netsurf.eclass
+
repoman-2.3.22
==================================
* Bug Fixes:
diff --git a/repoman/lib/repoman/__init__.py b/repoman/lib/repoman/__init__.py
index 4f3e59e50..fda942c92 100644
--- a/repoman/lib/repoman/__init__.py
+++ b/repoman/lib/repoman/__init__.py
@@ -20,9 +20,6 @@ except ImportError as e:
sys.stderr.write(" "+str(e)+"\n\n")
raise
-if sys.hexversion >= 0x3000000:
- # pylint: disable=W0622
- long = int
VERSION = "HEAD"
@@ -62,10 +59,10 @@ if VERSION == 'HEAD':
head_timestamp = None
if len(output_lines) > 3:
try:
- head_timestamp = long(output_lines[3])
+ head_timestamp = int(output_lines[3])
except ValueError:
pass
- timestamp = long(time.time())
+ timestamp = int(time.time())
if head_timestamp is not None and timestamp > head_timestamp:
timestamp = timestamp - head_timestamp
if not patchlevel:
diff --git a/repoman/lib/repoman/actions.py b/repoman/lib/repoman/actions.py
index 387ba7800..1afc4acb1 100644
--- a/repoman/lib/repoman/actions.py
+++ b/repoman/lib/repoman/actions.py
@@ -2,7 +2,7 @@
# Copyright 1999-2019 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
import errno
import io
@@ -41,7 +41,7 @@ from repoman import VERSION
bad = create_color_func("BAD")
-class Actions(object):
+class Actions:
'''Handles post check result output and performs
the various vcs activities for committing the results'''
diff --git a/repoman/lib/repoman/copyrights.py b/repoman/lib/repoman/copyrights.py
index 275dcbc3f..9e5a32e34 100644
--- a/repoman/lib/repoman/copyrights.py
+++ b/repoman/lib/repoman/copyrights.py
@@ -20,7 +20,7 @@ _copyright_re2 = \
re.compile(br'^(# Copyright )(\d\d\d\d)( Gentoo (Foundation|Authors))\b')
-class _copyright_repl(object):
+class _copyright_repl:
__slots__ = ('year',)
def __init__(self, year):
diff --git a/repoman/lib/repoman/errors.py b/repoman/lib/repoman/errors.py
index 9cf113ba0..3509ecc06 100644
--- a/repoman/lib/repoman/errors.py
+++ b/repoman/lib/repoman/errors.py
@@ -1,6 +1,6 @@
# -*- coding:utf-8 -*-
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
import sys
diff --git a/repoman/lib/repoman/gpg.py b/repoman/lib/repoman/gpg.py
index 7dac46f41..4e55a6e37 100644
--- a/repoman/lib/repoman/gpg.py
+++ b/repoman/lib/repoman/gpg.py
@@ -1,6 +1,6 @@
# -*- coding:utf-8 -*-
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
import errno
import logging
diff --git a/repoman/lib/repoman/main.py b/repoman/lib/repoman/main.py
index 731e8eae2..38c6a1759 100755
--- a/repoman/lib/repoman/main.py
+++ b/repoman/lib/repoman/main.py
@@ -3,7 +3,7 @@
# Copyright 1999-2017 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
import io
import logging
@@ -36,8 +36,6 @@ from repoman import utilities
from repoman.modules.vcs.settings import VCSSettings
from repoman import VERSION
-if sys.hexversion >= 0x3000000:
- basestring = str
bad = create_color_func("BAD")
diff --git a/repoman/lib/repoman/metadata.py b/repoman/lib/repoman/metadata.py
index 4537d2ce2..2aaedd4b0 100644
--- a/repoman/lib/repoman/metadata.py
+++ b/repoman/lib/repoman/metadata.py
@@ -1,6 +1,6 @@
# -*- coding:utf-8 -*-
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
import errno
import logging
@@ -14,11 +14,6 @@ from portage import os
from portage.output import green
from portage.package.ebuild.fetch import fetch
-if sys.hexversion >= 0x3000000:
- basestring = str
-
-if sys.hexversion >= 0x3000000:
- basestring = str
# Note: This URI is hardcoded in all metadata.xml files. We can't
# change it without updating all the xml files in the tree.
diff --git a/repoman/lib/repoman/modules/commit/manifest.py b/repoman/lib/repoman/modules/commit/manifest.py
index 573710a62..e71c1abcb 100644
--- a/repoman/lib/repoman/modules/commit/manifest.py
+++ b/repoman/lib/repoman/modules/commit/manifest.py
@@ -11,7 +11,7 @@ from portage.package.ebuild.digestgen import digestgen
from portage.util import writemsg_level
-class Manifest(object):
+class Manifest:
'''Creates as well as checks pkg Manifest entries/files'''
def __init__(self, **kwargs):
diff --git a/repoman/lib/repoman/modules/commit/repochecks.py b/repoman/lib/repoman/modules/commit/repochecks.py
index bedbdaf34..523d414d2 100644
--- a/repoman/lib/repoman/modules/commit/repochecks.py
+++ b/repoman/lib/repoman/modules/commit/repochecks.py
@@ -1,6 +1,6 @@
# -*- coding:utf-8 -*-
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
from portage.output import red
diff --git a/repoman/lib/repoman/modules/linechecks/base.py b/repoman/lib/repoman/modules/linechecks/base.py
index 39d7ebd78..bcd86773b 100644
--- a/repoman/lib/repoman/modules/linechecks/base.py
+++ b/repoman/lib/repoman/modules/linechecks/base.py
@@ -3,7 +3,7 @@ import logging
import re
-class LineCheck(object):
+class LineCheck:
"""Run a check on a line of an ebuild."""
"""A regular expression to determine whether to ignore the line"""
ignore_line = False
diff --git a/repoman/lib/repoman/modules/linechecks/config.py b/repoman/lib/repoman/modules/linechecks/config.py
index 6e4c5314e..69cf8e8aa 100644
--- a/repoman/lib/repoman/modules/linechecks/config.py
+++ b/repoman/lib/repoman/modules/linechecks/config.py
@@ -6,8 +6,6 @@
"""This module contains functions used in Repoman to ascertain the quality
and correctness of an ebuild."""
-from __future__ import unicode_literals
-
import collections
import logging
import os
@@ -37,7 +35,7 @@ def merge(dict1, dict2):
return result
-class LineChecksConfig(object):
+class LineChecksConfig:
'''Holds our LineChecks configuration data and operation functions'''
def __init__(self, repo_settings):
diff --git a/repoman/lib/repoman/modules/linechecks/controller.py b/repoman/lib/repoman/modules/linechecks/controller.py
index a3dfd9bd1..50ca5229f 100644
--- a/repoman/lib/repoman/modules/linechecks/controller.py
+++ b/repoman/lib/repoman/modules/linechecks/controller.py
@@ -18,7 +18,7 @@ MODULES_PATH = os.path.dirname(__file__)
logging.debug("LineChecks module path: %s", MODULES_PATH)
-class LineCheckController(object):
+class LineCheckController:
'''Initializes and runs the LineCheck checks'''
def __init__(self, repo_settings, linechecks):
diff --git a/repoman/lib/repoman/modules/linechecks/deprecated/inherit.py b/repoman/lib/repoman/modules/linechecks/deprecated/inherit.py
index f307d46fd..60410347b 100644
--- a/repoman/lib/repoman/modules/linechecks/deprecated/inherit.py
+++ b/repoman/lib/repoman/modules/linechecks/deprecated/inherit.py
@@ -17,6 +17,7 @@ class InheritDeprecated(LineCheck):
"bash-completion": "bash-completion-r1",
"boost-utils": False,
"clutter": "gnome2",
+ "cmake-utils": "cmake",
"confutils": False,
"distutils": "distutils-r1",
"epatch": "(eapply since EAPI 6)",
@@ -32,6 +33,7 @@ class InheritDeprecated(LineCheck):
"gst-plugins10": "gstreamer",
"ltprune": False,
"mono": "mono-env",
+ "netsurf": False,
"python": "python-r1 / python-single-r1 / python-any-r1",
"ruby": "ruby-ng",
"user": "GLEP 81",
diff --git a/repoman/lib/repoman/modules/scan/ebuild/ebuild.py b/repoman/lib/repoman/modules/scan/ebuild/ebuild.py
index 70011e387..14d6178d7 100644
--- a/repoman/lib/repoman/modules/scan/ebuild/ebuild.py
+++ b/repoman/lib/repoman/modules/scan/ebuild/ebuild.py
@@ -1,6 +1,6 @@
# -*- coding:utf-8 -*-
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
import re
import stat
diff --git a/repoman/lib/repoman/modules/scan/metadata/ebuild_metadata.py b/repoman/lib/repoman/modules/scan/metadata/ebuild_metadata.py
index 2edf8f7f2..6c0822897 100644
--- a/repoman/lib/repoman/modules/scan/metadata/ebuild_metadata.py
+++ b/repoman/lib/repoman/modules/scan/metadata/ebuild_metadata.py
@@ -5,9 +5,6 @@
import re
import sys
-if sys.hexversion >= 0x3000000:
- basestring = str
-
from repoman.modules.scan.scanbase import ScanBase
from portage.dep import use_reduce
@@ -24,7 +21,7 @@ class EbuildMetadata(ScanBase):
def invalidchar(self, **kwargs):
ebuild = kwargs.get('ebuild').get()
for k, v in ebuild.metadata.items():
- if not isinstance(v, basestring):
+ if not isinstance(v, str):
continue
m = NON_ASCII_RE.search(v)
if m is not None:
diff --git a/repoman/lib/repoman/modules/scan/metadata/use_flags.py b/repoman/lib/repoman/modules/scan/metadata/use_flags.py
index 1738fd23e..d9ce8bee9 100644
--- a/repoman/lib/repoman/modules/scan/metadata/use_flags.py
+++ b/repoman/lib/repoman/modules/scan/metadata/use_flags.py
@@ -11,7 +11,7 @@ from portage import eapi
from portage.eapi import eapi_has_iuse_defaults, eapi_has_required_use
-class USEFlagChecks(object):
+class USEFlagChecks:
'''Performs checks on USE flags listed in the ebuilds and metadata.xml'''
def __init__(self, **kwargs):
diff --git a/repoman/lib/repoman/modules/scan/module.py b/repoman/lib/repoman/modules/scan/module.py
index baed68989..3321cb224 100644
--- a/repoman/lib/repoman/modules/scan/module.py
+++ b/repoman/lib/repoman/modules/scan/module.py
@@ -19,7 +19,7 @@ MODULES_PATH = os.path.dirname(__file__)
logging.debug("module path: %s", MODULES_PATH)
-class ModuleConfig(object):
+class ModuleConfig:
'''Holds the scan modules configuration information and
creates the ordered list of modulles to run'''
diff --git a/repoman/lib/repoman/modules/scan/scanbase.py b/repoman/lib/repoman/modules/scan/scanbase.py
index aea1bb121..8d7b46336 100644
--- a/repoman/lib/repoman/modules/scan/scanbase.py
+++ b/repoman/lib/repoman/modules/scan/scanbase.py
@@ -1,7 +1,7 @@
# -*- coding:utf-8 -*-
-class ScanBase(object):
+class ScanBase:
'''Skeleton class for performing a scan for one or more items
to check in a pkg directory or ebuild.'''
diff --git a/repoman/lib/repoman/modules/vcs/None/status.py b/repoman/lib/repoman/modules/vcs/None/status.py
index d6e5ca0e4..bd318b4a8 100644
--- a/repoman/lib/repoman/modules/vcs/None/status.py
+++ b/repoman/lib/repoman/modules/vcs/None/status.py
@@ -3,7 +3,7 @@ None (non-VCS) module Status class submodule
'''
-class Status(object):
+class Status:
'''Performs status checks on the svn repository'''
def __init__(self, qatracker, eadded):
diff --git a/repoman/lib/repoman/modules/vcs/bzr/status.py b/repoman/lib/repoman/modules/vcs/bzr/status.py
index 199e7f399..f4a1a73e2 100644
--- a/repoman/lib/repoman/modules/vcs/bzr/status.py
+++ b/repoman/lib/repoman/modules/vcs/bzr/status.py
@@ -7,7 +7,7 @@ from portage import os
from repoman._subprocess import repoman_popen
-class Status(object):
+class Status:
'''Performs status checks on the svn repository'''
def __init__(self, qatracker, eadded):
diff --git a/repoman/lib/repoman/modules/vcs/changes.py b/repoman/lib/repoman/modules/vcs/changes.py
index aa4923f8f..3a19ae146 100644
--- a/repoman/lib/repoman/modules/vcs/changes.py
+++ b/repoman/lib/repoman/modules/vcs/changes.py
@@ -13,7 +13,7 @@ from portage import _unicode_encode
from portage.process import spawn
-class ChangesBase(object):
+class ChangesBase:
'''Base Class object to scan and hold the resultant data
for all changes to process.
'''
diff --git a/repoman/lib/repoman/modules/vcs/cvs/status.py b/repoman/lib/repoman/modules/vcs/cvs/status.py
index 3ec88f125..13c8b3450 100644
--- a/repoman/lib/repoman/modules/vcs/cvs/status.py
+++ b/repoman/lib/repoman/modules/vcs/cvs/status.py
@@ -13,7 +13,7 @@ from portage.output import red, green
from portage import _unicode_encode, _unicode_decode
-class Status(object):
+class Status:
'''Performs status checks on the svn repository'''
def __init__(self, qatracker, eadded):
diff --git a/repoman/lib/repoman/modules/vcs/git/status.py b/repoman/lib/repoman/modules/vcs/git/status.py
index e5aa9c741..374cb69c9 100644
--- a/repoman/lib/repoman/modules/vcs/git/status.py
+++ b/repoman/lib/repoman/modules/vcs/git/status.py
@@ -9,7 +9,7 @@ from portage import os
from repoman._subprocess import repoman_popen, repoman_getstatusoutput
-class Status(object):
+class Status:
'''Performs status checks on the git repository'''
def __init__(self, qatracker, eadded):
diff --git a/repoman/lib/repoman/modules/vcs/hg/status.py b/repoman/lib/repoman/modules/vcs/hg/status.py
index 8443554f5..2f9f0ba76 100644
--- a/repoman/lib/repoman/modules/vcs/hg/status.py
+++ b/repoman/lib/repoman/modules/vcs/hg/status.py
@@ -7,7 +7,7 @@ from portage import os
from repoman._subprocess import repoman_popen
-class Status(object):
+class Status:
'''Performs status checks on the svn repository'''
def __init__(self, qatracker, eadded):
diff --git a/repoman/lib/repoman/modules/vcs/settings.py b/repoman/lib/repoman/modules/vcs/settings.py
index a8e91dd27..f90f05963 100644
--- a/repoman/lib/repoman/modules/vcs/settings.py
+++ b/repoman/lib/repoman/modules/vcs/settings.py
@@ -2,7 +2,7 @@
Repoman VCSSettings modules
'''
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
import logging
import sys
@@ -13,7 +13,7 @@ from repoman.modules.vcs.vcs import FindVCS
from repoman.qa_tracker import QATracker
-class VCSSettings(object):
+class VCSSettings:
'''Holds various VCS settings'''
def __init__(self, options=None, repoman_settings=None, repo_settings=None):
diff --git a/repoman/lib/repoman/modules/vcs/svn/status.py b/repoman/lib/repoman/modules/vcs/svn/status.py
index 6575fe0b0..568670a4b 100644
--- a/repoman/lib/repoman/modules/vcs/svn/status.py
+++ b/repoman/lib/repoman/modules/vcs/svn/status.py
@@ -15,7 +15,7 @@ from portage import _unicode_encode, _unicode_decode
from repoman._subprocess import repoman_popen
-class Status(object):
+class Status:
'''Performs status checks on the svn repository'''
def __init__(self, qatracker, eadded):
diff --git a/repoman/lib/repoman/modules/vcs/vcs.py b/repoman/lib/repoman/modules/vcs/vcs.py
index b4ff3dc9c..b19f486a8 100644
--- a/repoman/lib/repoman/modules/vcs/vcs.py
+++ b/repoman/lib/repoman/modules/vcs/vcs.py
@@ -1,6 +1,6 @@
# -*- coding:utf-8 -*-
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
import collections
import logging
diff --git a/repoman/lib/repoman/profile.py b/repoman/lib/repoman/profile.py
index 50da91728..b17389c55 100644
--- a/repoman/lib/repoman/profile.py
+++ b/repoman/lib/repoman/profile.py
@@ -1,13 +1,13 @@
# -*- coding:utf-8 -*-
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
from portage import normalize_path
from portage import os
from portage.output import red
-class ProfileDesc(object):
+class ProfileDesc:
__slots__ = ('abs_path', 'arch', 'status', 'sub_path', 'tree_path',)
def __init__(self, arch, status, sub_path, tree_path):
diff --git a/repoman/lib/repoman/qa_data.py b/repoman/lib/repoman/qa_data.py
index 01141a617..afb403d8d 100644
--- a/repoman/lib/repoman/qa_data.py
+++ b/repoman/lib/repoman/qa_data.py
@@ -11,7 +11,7 @@ from repoman._portage import portage
from repoman.config import load_config
-class QAData(object):
+class QAData:
def __init__(self):
# Create the main exported data variables
diff --git a/repoman/lib/repoman/qa_tracker.py b/repoman/lib/repoman/qa_tracker.py
index faaf8e398..12e1b88bc 100644
--- a/repoman/lib/repoman/qa_tracker.py
+++ b/repoman/lib/repoman/qa_tracker.py
@@ -3,7 +3,7 @@ import logging
import sys
-class QATracker(object):
+class QATracker:
'''Track all occurrances of Q/A problems detected'''
def __init__(self, qacats=None, qawarnings=None):
diff --git a/repoman/lib/repoman/repos.py b/repoman/lib/repoman/repos.py
index 9c820b08c..515c8cbc6 100644
--- a/repoman/lib/repoman/repos.py
+++ b/repoman/lib/repoman/repos.py
@@ -22,7 +22,7 @@ GPG_KEY_ID_REGEX = r'(0x)?([0-9a-fA-F]{8}){1,5}!?'
bad = portage.output.create_color_func("BAD")
-class RepoSettings(object):
+class RepoSettings:
'''Holds our repo specific settings'''
def __init__(
diff --git a/repoman/lib/repoman/scanner.py b/repoman/lib/repoman/scanner.py
index 5db54bb97..8d2ce9052 100644
--- a/repoman/lib/repoman/scanner.py
+++ b/repoman/lib/repoman/scanner.py
@@ -1,6 +1,6 @@
# -*- coding:utf-8 -*-
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
import logging
from itertools import chain
@@ -24,7 +24,7 @@ from repoman.modules.vcs.vcs import vcs_files_to_cps
DATA_TYPES = {'dict': dict, 'Future': ExtendedFuture, 'list': list, 'set': set}
-class Scanner(object):
+class Scanner:
'''Primary scan class. Operates all the small Q/A tests and checks'''
def __init__(self, repo_settings, myreporoot, config_root, options,
diff --git a/repoman/lib/repoman/utilities.py b/repoman/lib/repoman/utilities.py
index 790d5e516..2d25fd309 100644
--- a/repoman/lib/repoman/utilities.py
+++ b/repoman/lib/repoman/utilities.py
@@ -6,7 +6,7 @@
"""This module contains utility functions to help repoman find ebuilds to
scan"""
-from __future__ import print_function, unicode_literals
+from __future__ import print_function
__all__ = [
"editor_is_executable",
@@ -50,9 +50,6 @@ from repoman.copyrights import update_copyright, update_copyright_year
normalize_path = util.normalize_path
util.initialize_logger()
-if sys.hexversion >= 0x3000000:
- basestring = str
-
def have_profile_dir(path, maxdepth=3, filename="profiles.desc"):
"""
diff --git a/repoman/setup.py b/repoman/setup.py
index c3a7adad9..f2664fae4 100755
--- a/repoman/setup.py
+++ b/repoman/setup.py
@@ -450,7 +450,7 @@ def get_manpages():
setup(
name = 'repoman',
- version = '2.3.22',
+ version = '2.3.23',
url = 'https://wiki.gentoo.org/wiki/Project:Portage',
author = 'Gentoo Portage Development Team',
author_email = 'dev-portage@gentoo.org',
@@ -492,7 +492,7 @@ setup(
'Intended Audience :: System Administrators',
'License :: OSI Approved :: GNU General Public License v2 (GPLv2)',
'Operating System :: POSIX',
- 'Programming Language :: Python',
+ 'Programming Language :: Python :: 3',
'Topic :: System :: Installation/Setup'
]
)
diff --git a/runtests b/runtests
index 15cc0bc77..9bc5dfced 100755
--- a/runtests
+++ b/runtests
@@ -23,7 +23,6 @@ import tempfile
# These are the versions we fully support and require to pass tests.
PYTHON_SUPPORTED_VERSIONS = [
- '2.7',
'3.6',
'3.7',
'3.8'
@@ -37,7 +36,7 @@ PYTHON_NICE_VERSIONS = [
EPREFIX = os.environ.get('PORTAGE_OVERRIDE_EPREFIX', '/')
-class Colors(object):
+class Colors:
"""Simple object holding color constants."""
_COLORS_YES = ('y', 'yes', 'true')
diff --git a/setup.py b/setup.py
index 7d8cdcd04..bef5c31fa 100755
--- a/setup.py
+++ b/setup.py
@@ -657,7 +657,7 @@ class build_ext(_build_ext):
setup(
name = 'portage',
- version = '2.3.100',
+ version = '3.0.1',
url = 'https://wiki.gentoo.org/wiki/Project:Portage',
author = 'Gentoo Portage Development Team',
author_email = 'dev-portage@gentoo.org',
@@ -714,7 +714,7 @@ setup(
'Intended Audience :: System Administrators',
'License :: OSI Approved :: GNU General Public License v2 (GPLv2)',
'Operating System :: POSIX',
- 'Programming Language :: Python',
+ 'Programming Language :: Python :: 3',
'Topic :: System :: Installation/Setup'
]
)
diff --git a/tox.ini b/tox.ini
index 79b5b45cb..050a2c455 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,14 +1,12 @@
[tox]
-envlist = py27,py36,py37,py38,py39,pypy3
+envlist = py36,py37,py38,py39,pypy3
skipsdist = True
[testenv]
deps =
pygost
pyyaml
- py27,py36,py37,py38,py39,pypy3: lxml!=4.2.0
- py27: pyblake2
- py27: pysha3
+ py36,py37,py38,py39,pypy3: lxml!=4.2.0
setenv =
PYTHONPATH={toxinidir}/lib
commands =