From 9ff4f05f1b18865110421526b906bdda8d7f538e Mon Sep 17 00:00:00 2001 From: John Sirois Date: Fri, 21 Jun 2019 17:54:43 -0600 Subject: [PATCH] Kill `AbstractClass` in favor of `abc.ABC{,Meta}`. Fixes #7927 --- .../go/src/python/pants/contrib/go/subsystems/BUILD | 1 - .../python/pants/contrib/go/subsystems/fetcher.py | 5 ++--- .../python/pants_test/contrib/go/targets/BUILD | 1 - .../contrib/go/targets/go_local_source_test_base.py | 5 ++--- .../src/python/pants/contrib/node/subsystems/BUILD | 1 - .../pants/contrib/node/subsystems/resolvers/BUILD | 1 - .../node/subsystems/resolvers/node_resolver_base.py | 5 ++--- .../python/pants/contrib/node/tasks/node_paths.py | 4 ++-- src/python/pants/backend/jvm/targets/BUILD | 1 - src/python/pants/backend/jvm/targets/credentials.py | 5 ++--- src/python/pants/backend/jvm/targets/jarable.py | 5 ++--- src/python/pants/backend/jvm/targets/jvm_binary.py | 4 ++-- src/python/pants/backend/jvm/tasks/BUILD | 3 --- .../pants/backend/jvm/tasks/coverage/engine.py | 5 ++--- src/python/pants/backend/jvm/tasks/jar_task.py | 7 +++---- .../backend/jvm/tasks/reports/junit_html_report.py | 5 ++--- src/python/pants/backend/jvm/tasks/rewrite_base.py | 5 ++--- src/python/pants/backend/native/config/BUILD | 1 - .../pants/backend/native/config/environment.py | 5 ++--- .../pants/backend/native/targets/native_library.py | 5 +++-- .../pants/backend/native/tasks/native_compile.py | 6 +++--- src/python/pants/backend/python/tasks/BUILD | 1 - src/python/pants/backend/python/tasks/setup_py.py | 5 ++--- src/python/pants/base/BUILD | 8 -------- src/python/pants/base/build_file.py | 4 ++-- src/python/pants/base/build_file_target_factory.py | 6 ++---- src/python/pants/base/fingerprint_strategy.py | 6 ++---- src/python/pants/base/payload_field.py | 5 ++--- src/python/pants/base/project_tree.py | 7 +++---- src/python/pants/base/specs.py | 5 ++--- src/python/pants/build_graph/address_mapper.py | 5 ++--- src/python/pants/build_graph/addressable.py | 5 ++--- src/python/pants/build_graph/build_graph.py | 5 ++--- .../build_graph/import_remote_sources_mixin.py | 6 +++--- .../build_graph/intermediate_target_factory.py | 4 ++-- .../build_graph/mirrored_target_option_mixin.py | 5 ++--- src/python/pants/cache/BUILD | 1 - src/python/pants/cache/resolver.py | 5 ++--- src/python/pants/engine/BUILD | 4 ---- src/python/pants/engine/goal.py | 8 ++++---- src/python/pants/engine/legacy/structs.py | 6 +++--- src/python/pants/engine/legacy_engine.py | 5 ++--- src/python/pants/engine/nodes.py | 4 ++-- src/python/pants/engine/objects.py | 13 ++++++------- src/python/pants/engine/parser.py | 5 ++--- src/python/pants/engine/rules.py | 5 ++--- src/python/pants/fs/BUILD | 1 - src/python/pants/fs/archive.py | 5 ++--- src/python/pants/goal/BUILD | 1 - src/python/pants/goal/workspace.py | 5 ++--- src/python/pants/invalidation/BUILD | 1 - src/python/pants/invalidation/build_invalidator.py | 5 ++--- src/python/pants/java/BUILD | 2 -- src/python/pants/java/distribution/distribution.py | 5 ++--- src/python/pants/java/executor.py | 5 ++--- src/python/pants/java/nailgun_protocol.py | 5 ++--- src/python/pants/net/BUILD | 1 - src/python/pants/net/http/fetcher.py | 5 ++--- src/python/pants/option/arg_splitter.py | 4 ++-- src/python/pants/option/config.py | 4 ++-- src/python/pants/option/optionable.py | 8 ++++---- src/python/pants/pantsd/service/BUILD | 2 +- src/python/pants/pantsd/service/pants_service.py | 5 ++--- src/python/pants/scm/BUILD | 1 - src/python/pants/scm/scm.py | 6 ++---- src/python/pants/source/wrapped_globs.py | 7 +++---- src/python/pants/task/task.py | 6 +++--- src/python/pants/task/unpack_remote_sources_base.py | 6 +++--- src/python/pants/util/BUILD | 1 - src/python/pants/util/meta.py | 9 +-------- src/python/pants/util/objects.py | 10 +++++----- src/python/pants/util/process_handler.py | 6 ++---- tests/python/pants_test/BUILD | 1 + .../backend/project_info/tasks/test_filedeps.py | 4 ++-- tests/python/pants_test/base/BUILD | 1 - .../pants_test/base/project_tree_test_base.py | 5 ++--- .../engine/legacy/test_changed_integration.py | 4 ++-- tests/python/pants_test/engine/test_fs.py | 13 ++++--------- tests/python/pants_test/test_base.py | 11 +++++------ tests/python/pants_test/util/test_meta.py | 10 +++++----- 80 files changed, 147 insertions(+), 231 deletions(-) diff --git a/contrib/go/src/python/pants/contrib/go/subsystems/BUILD b/contrib/go/src/python/pants/contrib/go/subsystems/BUILD index e8fa8bd4fea..be5090e2264 100644 --- a/contrib/go/src/python/pants/contrib/go/subsystems/BUILD +++ b/contrib/go/src/python/pants/contrib/go/subsystems/BUILD @@ -17,7 +17,6 @@ python_library( 'src/python/pants/subsystem', 'src/python/pants/util:contextutil', 'src/python/pants/util:memo', - 'src/python/pants/util:meta', 'src/python/pants/util:process_handler', ], ) diff --git a/contrib/go/src/python/pants/contrib/go/subsystems/fetcher.py b/contrib/go/src/python/pants/contrib/go/subsystems/fetcher.py index 2fc3975dceb..4a53aa1b113 100644 --- a/contrib/go/src/python/pants/contrib/go/subsystems/fetcher.py +++ b/contrib/go/src/python/pants/contrib/go/subsystems/fetcher.py @@ -5,11 +5,10 @@ from __future__ import absolute_import, division, print_function, unicode_literals import logging -from abc import abstractmethod +from abc import ABC, abstractmethod from collections import namedtuple from pants.scm.git import Git -from pants.util.meta import AbstractClass from pants.contrib.go.subsystems.fetch_error import FetchError from pants.contrib.go.targets.go_remote_library import GoRemoteLibrary @@ -18,7 +17,7 @@ logger = logging.getLogger(__name__) -class Fetcher(AbstractClass): +class Fetcher(ABC): """Knows how to interpret remote import paths and fetch code to satisfy them.""" def __init__(self, import_path): diff --git a/contrib/go/tests/python/pants_test/contrib/go/targets/BUILD b/contrib/go/tests/python/pants_test/contrib/go/targets/BUILD index 6bcc4649c80..de5be2f720a 100644 --- a/contrib/go/tests/python/pants_test/contrib/go/targets/BUILD +++ b/contrib/go/tests/python/pants_test/contrib/go/targets/BUILD @@ -6,7 +6,6 @@ python_library( dependencies=[ 'contrib/go/src/python/pants/contrib/go:plugin', 'src/python/pants/build_graph', - 'src/python/pants/util:meta', 'tests/python/pants_test:test_base', ] ) diff --git a/contrib/go/tests/python/pants_test/contrib/go/targets/go_local_source_test_base.py b/contrib/go/tests/python/pants_test/contrib/go/targets/go_local_source_test_base.py index 2a3dcdd9a4b..dd02755fea6 100644 --- a/contrib/go/tests/python/pants_test/contrib/go/targets/go_local_source_test_base.py +++ b/contrib/go/tests/python/pants_test/contrib/go/targets/go_local_source_test_base.py @@ -4,17 +4,16 @@ from __future__ import absolute_import, division, print_function, unicode_literals -from abc import abstractproperty +from abc import ABC, abstractproperty from textwrap import dedent from pants.build_graph.address_lookup_error import AddressLookupError -from pants.util.meta import AbstractClass from pants_test.test_base import TestBase from pants.contrib.go.register import build_file_aliases -class GoLocalSourceTestBase(AbstractClass): +class GoLocalSourceTestBase(ABC): # NB: We assume we're mixed into a TestBase - we can't extend that directly or else unittest tries # to run our test methods in the subclass (OK), and against us (not OK). # NB: We use aliases and BUILD files to test proper registration of anonymous targets and macros. diff --git a/contrib/node/src/python/pants/contrib/node/subsystems/BUILD b/contrib/node/src/python/pants/contrib/node/subsystems/BUILD index f901ada75df..db6cedb41c7 100644 --- a/contrib/node/src/python/pants/contrib/node/subsystems/BUILD +++ b/contrib/node/src/python/pants/contrib/node/subsystems/BUILD @@ -9,7 +9,6 @@ python_library( 'src/python/pants/subsystem', 'src/python/pants/util:contextutil', 'src/python/pants/util:memo', - 'src/python/pants/util:meta', 'src/python/pants/util:process_handler', ], ) diff --git a/contrib/node/src/python/pants/contrib/node/subsystems/resolvers/BUILD b/contrib/node/src/python/pants/contrib/node/subsystems/resolvers/BUILD index 10a9c7ba932..a43e44245e1 100644 --- a/contrib/node/src/python/pants/contrib/node/subsystems/resolvers/BUILD +++ b/contrib/node/src/python/pants/contrib/node/subsystems/resolvers/BUILD @@ -46,6 +46,5 @@ python_library( dependencies=[ 'src/python/pants/base:build_environment', 'src/python/pants/util:dirutil', - 'src/python/pants/util:meta', ] ) diff --git a/contrib/node/src/python/pants/contrib/node/subsystems/resolvers/node_resolver_base.py b/contrib/node/src/python/pants/contrib/node/subsystems/resolvers/node_resolver_base.py index e77f8d0bf4c..b3d3efb214f 100644 --- a/contrib/node/src/python/pants/contrib/node/subsystems/resolvers/node_resolver_base.py +++ b/contrib/node/src/python/pants/contrib/node/subsystems/resolvers/node_resolver_base.py @@ -7,14 +7,13 @@ import os import re import shutil -from abc import abstractmethod +from abc import ABC, abstractmethod from pants.base.build_environment import get_buildroot from pants.util.dirutil import safe_mkdir -from pants.util.meta import AbstractClass -class NodeResolverBase(AbstractClass): +class NodeResolverBase(ABC): file_regex = re.compile('^file:(.*)$') diff --git a/contrib/node/src/python/pants/contrib/node/tasks/node_paths.py b/contrib/node/src/python/pants/contrib/node/tasks/node_paths.py index 33e3127e599..fc4074eef0e 100644 --- a/contrib/node/src/python/pants/contrib/node/tasks/node_paths.py +++ b/contrib/node/src/python/pants/contrib/node/tasks/node_paths.py @@ -4,13 +4,13 @@ from __future__ import absolute_import, division, print_function, unicode_literals -from pants.util.meta import AbstractClass +from abc import ABC # TODO(John Sirois): UnionProducts? That seems broken though for ranged version constraints, # which npm has and are widely used in the community. For now stay dumb simple (and slow) and # resolve each node_module individually. -class NodePathsBase(AbstractClass): +class NodePathsBase(ABC): """Maps NpmPackage targets to their resolved NODE_PATH.""" def __init__(self): diff --git a/src/python/pants/backend/jvm/targets/BUILD b/src/python/pants/backend/jvm/targets/BUILD index 67418683401..b511971972e 100644 --- a/src/python/pants/backend/jvm/targets/BUILD +++ b/src/python/pants/backend/jvm/targets/BUILD @@ -44,7 +44,6 @@ python_library( 'src/python/pants/fs', 'src/python/pants/source', 'src/python/pants/util:memo', - 'src/python/pants/util:meta', 'src/python/pants/util:netrc', 'src/python/pants/util:objects', ], diff --git a/src/python/pants/backend/jvm/targets/credentials.py b/src/python/pants/backend/jvm/targets/credentials.py index 6cda8c78bf2..61357e3d67b 100644 --- a/src/python/pants/backend/jvm/targets/credentials.py +++ b/src/python/pants/backend/jvm/targets/credentials.py @@ -5,16 +5,15 @@ from __future__ import absolute_import, division, print_function, unicode_literals import functools -from abc import abstractmethod +from abc import ABCMeta, abstractmethod from pants.base.exceptions import TargetDefinitionException from pants.build_graph.target import Target from pants.util.memo import memoized_method -from pants.util.meta import AbstractClass from pants.util.netrc import Netrc -class Credentials(Target, AbstractClass): +class Credentials(Target, metaclass=ABCMeta): """Credentials for a maven repository. The ``publish.jar`` section of your ``pants.ini`` file can refer to one diff --git a/src/python/pants/backend/jvm/targets/jarable.py b/src/python/pants/backend/jvm/targets/jarable.py index 6ca2be6133d..ae687a157d2 100644 --- a/src/python/pants/backend/jvm/targets/jarable.py +++ b/src/python/pants/backend/jvm/targets/jarable.py @@ -4,13 +4,12 @@ from __future__ import absolute_import, division, print_function, unicode_literals -from abc import abstractproperty +from abc import ABC, abstractproperty from pants.java.jar.jar_dependency import JarDependency -from pants.util.meta import AbstractClass -class Jarable(AbstractClass): +class Jarable(ABC): """A mixin that identifies a target as one that can provide a jar. :API: public diff --git a/src/python/pants/backend/jvm/targets/jvm_binary.py b/src/python/pants/backend/jvm/targets/jvm_binary.py index 578b8b1f55e..1d0c1828484 100644 --- a/src/python/pants/backend/jvm/targets/jvm_binary.py +++ b/src/python/pants/backend/jvm/targets/jvm_binary.py @@ -5,6 +5,7 @@ from __future__ import absolute_import, division, print_function, unicode_literals import re +from abc import ABCMeta from hashlib import sha1 from future.utils import PY3, string_types @@ -16,10 +17,9 @@ PrimitiveField) from pants.base.validation import assert_list from pants.java.jar.exclude import Exclude -from pants.util.meta import AbstractClass -class JarRule(FingerprintedMixin, AbstractClass): +class JarRule(FingerprintedMixin, metaclass=ABCMeta): def __init__(self, apply_pattern, payload=None): self.payload = payload or Payload() diff --git a/src/python/pants/backend/jvm/tasks/BUILD b/src/python/pants/backend/jvm/tasks/BUILD index 9480abfe302..ffa58cdfe09 100644 --- a/src/python/pants/backend/jvm/tasks/BUILD +++ b/src/python/pants/backend/jvm/tasks/BUILD @@ -368,7 +368,6 @@ python_library( 'src/python/pants/binaries', 'src/python/pants/java/jar', 'src/python/pants/util:contextutil', - 'src/python/pants/util:meta', ], ) @@ -417,7 +416,6 @@ python_library( 'src/python/pants/util:desktop', 'src/python/pants/util:dirutil', 'src/python/pants/util:memo', - 'src/python/pants/util:meta', 'src/python/pants/util:process_handler', 'src/python/pants/util:strutil', ], @@ -718,7 +716,6 @@ python_library( 'src/python/pants/build_graph', 'src/python/pants/option', 'src/python/pants/util:dirutil', - 'src/python/pants/util:meta', 'src/python/pants/util:memo', ] ) diff --git a/src/python/pants/backend/jvm/tasks/coverage/engine.py b/src/python/pants/backend/jvm/tasks/coverage/engine.py index 9435658975f..f4b2af0eda2 100644 --- a/src/python/pants/backend/jvm/tasks/coverage/engine.py +++ b/src/python/pants/backend/jvm/tasks/coverage/engine.py @@ -4,16 +4,15 @@ from __future__ import absolute_import, division, print_function, unicode_literals -from abc import abstractmethod +from abc import ABC, abstractmethod from pants.backend.jvm.targets.annotation_processor import AnnotationProcessor from pants.backend.jvm.targets.java_library import JavaLibrary from pants.backend.jvm.targets.scala_library import ScalaLibrary -from pants.util.meta import AbstractClass from pants.util.objects import datatype -class CoverageEngine(AbstractClass): +class CoverageEngine(ABC): """The interface JVM code coverage processors must support. This is a stateful interface that will be called via the following sequence: diff --git a/src/python/pants/backend/jvm/tasks/jar_task.py b/src/python/pants/backend/jvm/tasks/jar_task.py index 68512d9d477..3a5b5f7fc85 100644 --- a/src/python/pants/backend/jvm/tasks/jar_task.py +++ b/src/python/pants/backend/jvm/tasks/jar_task.py @@ -7,7 +7,7 @@ import os import shutil import tempfile -from abc import abstractmethod +from abc import ABC, abstractmethod from builtins import bytes, object, open from contextlib import contextmanager @@ -25,7 +25,6 @@ from pants.java.util import relativize_classpath from pants.util.contextutil import temporary_dir from pants.util.dirutil import safe_mkdtemp -from pants.util.meta import AbstractClass class Jar(object): @@ -41,7 +40,7 @@ class Jar(object): class Error(Exception): """Indicates an error creating or updating a jar on disk.""" - class Entry(AbstractClass): + class Entry(ABC): """An entry to be written to a jar.""" def __init__(self, dest): @@ -363,7 +362,7 @@ def open_jar(self, path, overwrite=False, compressed=True, jar_rules=None): class JarBuilderTask(JarTask): - class JarBuilder(AbstractClass): + class JarBuilder(ABC): """A utility to aid in adding the classes and resources associated with targets to a jar. :API: public diff --git a/src/python/pants/backend/jvm/tasks/reports/junit_html_report.py b/src/python/pants/backend/jvm/tasks/reports/junit_html_report.py index 90230048ed4..5b005ddfbd2 100644 --- a/src/python/pants/backend/jvm/tasks/reports/junit_html_report.py +++ b/src/python/pants/backend/jvm/tasks/reports/junit_html_report.py @@ -9,7 +9,7 @@ import logging import os import xml.etree.ElementTree as ET -from abc import abstractmethod +from abc import ABC, abstractmethod from builtins import map, next, object, open from collections import defaultdict from functools import total_ordering @@ -17,7 +17,6 @@ from pants.base.mustache import MustacheRenderer from pants.util.dirutil import safe_mkdir_for, safe_walk from pants.util.memo import memoized_property -from pants.util.meta import AbstractClass from pants.util.objects import datatype @@ -173,7 +172,7 @@ def as_dict(self): return d -class JUnitHtmlReportInterface(AbstractClass): +class JUnitHtmlReportInterface(ABC): """The interface JUnit html reporters must support.""" @abstractmethod diff --git a/src/python/pants/backend/jvm/tasks/rewrite_base.py b/src/python/pants/backend/jvm/tasks/rewrite_base.py index cec7f273d8b..a9f7454f249 100644 --- a/src/python/pants/backend/jvm/tasks/rewrite_base.py +++ b/src/python/pants/backend/jvm/tasks/rewrite_base.py @@ -6,7 +6,7 @@ import os import shutil -from abc import abstractmethod, abstractproperty +from abc import ABCMeta, abstractmethod, abstractproperty from pants.backend.jvm.tasks.nailgun_task import NailgunTask from pants.base.build_environment import get_buildroot @@ -15,10 +15,9 @@ from pants.process.xargs import Xargs from pants.util.dirutil import fast_relpath, safe_mkdir_for_all from pants.util.memo import memoized_property -from pants.util.meta import AbstractClass -class RewriteBase(NailgunTask, AbstractClass): +class RewriteBase(NailgunTask, metaclass=ABCMeta): """Abstract base class for JVM-based tools that check/rewrite sources.""" @classmethod diff --git a/src/python/pants/backend/native/config/BUILD b/src/python/pants/backend/native/config/BUILD index bf24ed273a8..572ee78c077 100644 --- a/src/python/pants/backend/native/config/BUILD +++ b/src/python/pants/backend/native/config/BUILD @@ -6,7 +6,6 @@ python_library( dependencies=[ '3rdparty/python:future', 'src/python/pants/engine:rules', - 'src/python/pants/util:meta', 'src/python/pants/util:objects', 'src/python/pants/util:osutil', ], diff --git a/src/python/pants/backend/native/config/environment.py b/src/python/pants/backend/native/config/environment.py index 2cb07a9c2fb..16277e126de 100644 --- a/src/python/pants/backend/native/config/environment.py +++ b/src/python/pants/backend/native/config/environment.py @@ -5,11 +5,10 @@ from __future__ import absolute_import, division, print_function, unicode_literals import os -from abc import abstractmethod, abstractproperty +from abc import ABC, abstractmethod, abstractproperty from pants.engine.rules import rule from pants.util.memo import memoized_classproperty -from pants.util.meta import AbstractClass from pants.util.objects import datatype, enum from pants.util.osutil import all_normalized_os_names, get_normalized_os_name from pants.util.strutil import create_path_env_var @@ -45,7 +44,7 @@ def wrapper(cls): # NB: prototypal inheritance seems *deeply* linked with the idea here! # TODO: since we are calling these methods from other files, we should remove the leading underscore # and add testing! -class _ExtensibleAlgebraic(AbstractClass): +class _ExtensibleAlgebraic(ABC): """A mixin to make it more concise to coalesce datatypes with related collection fields.""" @memoized_classproperty diff --git a/src/python/pants/backend/native/targets/native_library.py b/src/python/pants/backend/native/targets/native_library.py index 20e331c0cdb..379e852c7ee 100644 --- a/src/python/pants/backend/native/targets/native_library.py +++ b/src/python/pants/backend/native/targets/native_library.py @@ -4,16 +4,17 @@ from __future__ import absolute_import, division, print_function, unicode_literals +from abc import ABCMeta + from pants.backend.native.subsystems.native_build_step import ToolchainVariant from pants.backend.native.targets.native_artifact import NativeArtifact from pants.base.exceptions import TargetDefinitionException from pants.base.payload import Payload from pants.base.payload_field import PrimitiveField, PrimitivesSetField from pants.build_graph.target import Target -from pants.util.meta import AbstractClass -class NativeLibrary(Target, AbstractClass): +class NativeLibrary(Target, metaclass=ABCMeta): """A class wrapping targets containing sources for C-family languages and related code.""" # TODO: replace this awkward classmethod with a mixin! diff --git a/src/python/pants/backend/native/tasks/native_compile.py b/src/python/pants/backend/native/tasks/native_compile.py index 0250544ed80..149baf19aba 100644 --- a/src/python/pants/backend/native/tasks/native_compile.py +++ b/src/python/pants/backend/native/tasks/native_compile.py @@ -5,7 +5,7 @@ from __future__ import absolute_import, division, print_function, unicode_literals import os -from abc import abstractmethod +from abc import ABCMeta, abstractmethod from collections import defaultdict from pants.backend.native.tasks.native_task import NativeTask @@ -13,7 +13,7 @@ from pants.base.exceptions import TaskError from pants.base.workunit import WorkUnit, WorkUnitLabel from pants.util.memo import memoized_method, memoized_property -from pants.util.meta import AbstractClass, classproperty +from pants.util.meta import classproperty from pants.util.objects import datatype from pants.util.process_handler import subprocess @@ -36,7 +36,7 @@ def file_paths(self): return [os.path.join(self.root_dir, fname) for fname in self.filenames] -class NativeCompile(NativeTask, AbstractClass): +class NativeCompile(NativeTask, metaclass=ABCMeta): # `NativeCompile` will use the `source_target_constraint` to determine what targets have "sources" # to compile, and the `dependent_target_constraint` to determine which dependent targets to # operate on for `strict_deps` calculation. diff --git a/src/python/pants/backend/python/tasks/BUILD b/src/python/pants/backend/python/tasks/BUILD index 47ab3807e03..0f3e849bcaf 100644 --- a/src/python/pants/backend/python/tasks/BUILD +++ b/src/python/pants/backend/python/tasks/BUILD @@ -32,7 +32,6 @@ python_library( 'src/python/pants/util:dirutil', 'src/python/pants/util:fileutil', 'src/python/pants/util:memo', - 'src/python/pants/util:meta', 'src/python/pants/util:objects', 'src/python/pants/util:process_handler', 'src/python/pants/util:py2_compat', diff --git a/src/python/pants/backend/python/tasks/setup_py.py b/src/python/pants/backend/python/tasks/setup_py.py index d2d7b020d58..0842b41cb59 100644 --- a/src/python/pants/backend/python/tasks/setup_py.py +++ b/src/python/pants/backend/python/tasks/setup_py.py @@ -10,7 +10,7 @@ import os import shutil import textwrap -from abc import abstractmethod +from abc import ABC, abstractmethod from builtins import bytes, map, object, str, zip from collections import defaultdict @@ -38,7 +38,6 @@ from pants.util.contextutil import temporary_file from pants.util.dirutil import safe_concurrent_creation, safe_rmtree, safe_walk from pants.util.memo import memoized_property -from pants.util.meta import AbstractClass from pants.util.process_handler import subprocess from pants.util.strutil import ensure_binary, ensure_text, safe_shlex_split @@ -163,7 +162,7 @@ def iter_siblings_and_ancestors(spec_path): # un-exported non-3rdparty interior nodes as needed. It seems like the latter is preferable since # it can be used with a BUILD graph validator requiring completely exported subgraphs to enforce the # former as a matter of local repo policy. -class ExportedTargetDependencyCalculator(AbstractClass): +class ExportedTargetDependencyCalculator(ABC): """Calculates the dependencies of exported targets. When a target is exported many of its internal transitive library dependencies may be satisfied by diff --git a/src/python/pants/base/BUILD b/src/python/pants/base/BUILD index 514fb274169..e5a0522133e 100644 --- a/src/python/pants/base/BUILD +++ b/src/python/pants/base/BUILD @@ -24,7 +24,6 @@ python_library( ':build_environment', 'src/python/pants/util:dirutil', 'src/python/pants/util:memo', - 'src/python/pants/util:meta', 'src/python/pants/util:objects', ] ) @@ -36,7 +35,6 @@ python_library( '3rdparty/python/twitter/commons:twitter.common.collections', '3rdparty/python:pathspec', 'src/python/pants/util:dirutil', - 'src/python/pants/util:meta', ':project_tree', ] ) @@ -44,9 +42,6 @@ python_library( python_library( name = 'build_file_target_factory', sources = ['build_file_target_factory.py'], - dependencies = [ - 'src/python/pants/util:meta', - ] ) python_library( @@ -95,7 +90,6 @@ python_library( dependencies = [ '3rdparty/python:future', ':deprecated', - 'src/python/pants/util:meta', ] ) @@ -154,7 +148,6 @@ python_library( '3rdparty/python/twitter/commons:twitter.common.collections', ':deprecated', ':hash_utils', - 'src/python/pants/util:meta', ] ) @@ -164,7 +157,6 @@ python_library( dependencies = [ 'src/python/pants/util:collections', 'src/python/pants/util:dirutil', - 'src/python/pants/util:meta', 'src/python/pants/util:objects', ], ) diff --git a/src/python/pants/base/build_file.py b/src/python/pants/base/build_file.py index b1405a72c3d..d297333f613 100644 --- a/src/python/pants/base/build_file.py +++ b/src/python/pants/base/build_file.py @@ -7,12 +7,12 @@ import logging import os import re +from abc import ABC from pathspec import PathSpec from twitter.common.collections import OrderedSet from pants.util.dirutil import fast_relpath -from pants.util.meta import AbstractClass logger = logging.getLogger(__name__) @@ -20,7 +20,7 @@ # Note: Significant effort has been made to keep the types BuildFile, BuildGraph, Address, and # Target separated appropriately. Don't add references to those other types to this module. -class BuildFile(AbstractClass): +class BuildFile(ABC): class BuildFileError(Exception): """Base class for all exceptions raised in BuildFile to make exception handling easier""" diff --git a/src/python/pants/base/build_file_target_factory.py b/src/python/pants/base/build_file_target_factory.py index fc99bd078d1..a40a0da1354 100644 --- a/src/python/pants/base/build_file_target_factory.py +++ b/src/python/pants/base/build_file_target_factory.py @@ -4,12 +4,10 @@ from __future__ import absolute_import, division, print_function, unicode_literals -from abc import abstractproperty +from abc import ABC, abstractproperty -from pants.util.meta import AbstractClass - -class BuildFileTargetFactory(AbstractClass): +class BuildFileTargetFactory(ABC): """An object that can hydrate target types from BUILD files.""" @abstractproperty diff --git a/src/python/pants/base/fingerprint_strategy.py b/src/python/pants/base/fingerprint_strategy.py index 3edf3ccc022..87262c71ee7 100644 --- a/src/python/pants/base/fingerprint_strategy.py +++ b/src/python/pants/base/fingerprint_strategy.py @@ -5,11 +5,9 @@ from __future__ import absolute_import, division, print_function, unicode_literals import logging -from abc import abstractmethod +from abc import ABC, abstractmethod from builtins import object -from pants.util.meta import AbstractClass - logger = logging.getLogger(__name__) @@ -28,7 +26,7 @@ def __eq__(self, other): return type(self) == type(other) -class FingerprintStrategy(AbstractClass): +class FingerprintStrategy(ABC): """A helper object for doing per-task, finer grained invalidation of Targets.""" @abstractmethod diff --git a/src/python/pants/base/payload_field.py b/src/python/pants/base/payload_field.py index dc0ca75bc91..5dc6af6cbfd 100644 --- a/src/python/pants/base/payload_field.py +++ b/src/python/pants/base/payload_field.py @@ -4,7 +4,7 @@ from __future__ import absolute_import, division, print_function, unicode_literals -from abc import abstractmethod +from abc import ABC, abstractmethod from builtins import object from hashlib import sha1 @@ -12,7 +12,6 @@ from twitter.common.collections import OrderedSet from pants.base.hash_utils import stable_json_sha1 -from pants.util.meta import AbstractClass from pants.util.strutil import ensure_binary @@ -25,7 +24,7 @@ def combine_hashes(hashes): return hasher.hexdigest() if PY3 else hasher.hexdigest().decode('utf-8') -class PayloadField(AbstractClass): +class PayloadField(ABC): """An immutable, hashable structure to be mixed into Payload instances. :API: public diff --git a/src/python/pants/base/project_tree.py b/src/python/pants/base/project_tree.py index c14a685b027..bb7d63925e9 100644 --- a/src/python/pants/base/project_tree.py +++ b/src/python/pants/base/project_tree.py @@ -6,20 +6,19 @@ import logging import os -from abc import abstractmethod, abstractproperty +from abc import ABC, abstractmethod, abstractproperty from pathspec.pathspec import PathSpec from pathspec.patterns.gitwildmatch import GitWildMatchPattern from pants.util.dirutil import fast_relpath -from pants.util.meta import AbstractClass from pants.util.objects import datatype logger = logging.getLogger(__name__) -class ProjectTree(AbstractClass): +class ProjectTree(ABC): """Represents project tree which is used to locate and read build files. Has two implementations: one backed by file system and one backed by SCM. """ @@ -197,7 +196,7 @@ def _append_slash_if_dir_path(self, relpath): return relpath -class Stat(AbstractClass): +class Stat(ABC): """An existing filesystem path with a known type, relative to the ProjectTree's buildroot. Note that in order to preserve these invariants, end-user functions should never directly diff --git a/src/python/pants/base/specs.py b/src/python/pants/base/specs.py index f6be445fdc9..fd96e420632 100644 --- a/src/python/pants/base/specs.py +++ b/src/python/pants/base/specs.py @@ -6,18 +6,17 @@ import os import re -from abc import abstractmethod +from abc import ABC, abstractmethod from builtins import str from pants.util.collections import assert_single_element from pants.util.dirutil import fast_relpath_optional, recursive_dirname from pants.util.filtering import create_filters, wrap_filters from pants.util.memo import memoized_property -from pants.util.meta import AbstractClass from pants.util.objects import datatype -class Spec(AbstractClass): +class Spec(ABC): """Represents address selectors as passed from the command line. Supports `Single` target addresses as well as `Sibling` (:) and `Descendant` (::) selector forms. diff --git a/src/python/pants/build_graph/address_mapper.py b/src/python/pants/build_graph/address_mapper.py index d3794d11f45..3cad469a6c8 100644 --- a/src/python/pants/build_graph/address_mapper.py +++ b/src/python/pants/build_graph/address_mapper.py @@ -5,17 +5,16 @@ from __future__ import absolute_import, division, print_function, unicode_literals import logging -from abc import abstractmethod +from abc import ABC, abstractmethod from pants.base.specs import SingleAddress from pants.build_graph.address_lookup_error import AddressLookupError -from pants.util.meta import AbstractClass logger = logging.getLogger(__name__) -class AddressMapper(AbstractClass): +class AddressMapper(ABC): """Maps specs into valid addresses and their associated addressables.""" class AddressNotInBuildFile(AddressLookupError): diff --git a/src/python/pants/build_graph/addressable.py b/src/python/pants/build_graph/addressable.py index 36d53fd7192..163a6913400 100644 --- a/src/python/pants/build_graph/addressable.py +++ b/src/python/pants/build_graph/addressable.py @@ -5,11 +5,10 @@ from __future__ import absolute_import, division, print_function, unicode_literals import os -from abc import abstractmethod +from abc import ABC, abstractmethod from pants.base.build_file_target_factory import BuildFileTargetFactory from pants.build_graph.address import BuildFileAddress -from pants.util.meta import AbstractClass class AddressableCallProxy(BuildFileTargetFactory): @@ -51,7 +50,7 @@ def __repr__(self): .format(self._addressable_factory, self._build_file)) -class Addressable(AbstractClass): +class Addressable(ABC): """An ABC for classes which would like instances to be named and exported from BUILD files.""" class Factory(BuildFileTargetFactory): diff --git a/src/python/pants/build_graph/build_graph.py b/src/python/pants/build_graph/build_graph.py index d533657c3b2..bca824eae71 100644 --- a/src/python/pants/build_graph/build_graph.py +++ b/src/python/pants/build_graph/build_graph.py @@ -7,7 +7,7 @@ import itertools import logging import weakref -from abc import abstractmethod +from abc import ABC, abstractmethod from builtins import filter, object from collections import defaultdict, deque @@ -18,13 +18,12 @@ from pants.build_graph.injectables_mixin import InjectablesMixin from pants.build_graph.target import Target from pants.util.collections_abc_backport import OrderedDict -from pants.util.meta import AbstractClass logger = logging.getLogger(__name__) -class BuildGraph(AbstractClass): +class BuildGraph(ABC): """A directed acyclic graph of Targets and dependencies. Not necessarily connected. :API: public diff --git a/src/python/pants/build_graph/import_remote_sources_mixin.py b/src/python/pants/build_graph/import_remote_sources_mixin.py index 1fc22f9fc05..f035b161e25 100644 --- a/src/python/pants/build_graph/import_remote_sources_mixin.py +++ b/src/python/pants/build_graph/import_remote_sources_mixin.py @@ -4,7 +4,7 @@ from __future__ import absolute_import, division, print_function, unicode_literals -from abc import abstractmethod +from abc import ABCMeta, abstractmethod from builtins import str from future.utils import string_types @@ -12,11 +12,11 @@ from pants.build_graph.address_lookup_error import AddressLookupError from pants.build_graph.target import Target from pants.util.memo import memoized_property -from pants.util.meta import AbstractClass, classproperty +from pants.util.meta import classproperty from pants.util.objects import TypeConstraintError -class ImportRemoteSourcesMixin(Target, AbstractClass): +class ImportRemoteSourcesMixin(Target, metaclass=ABCMeta): """A Target Mixin to be used when a target declares another target type to be imported.""" class ExpectedAddressError(AddressLookupError): diff --git a/src/python/pants/build_graph/intermediate_target_factory.py b/src/python/pants/build_graph/intermediate_target_factory.py index 2ae267c0dcd..dc4a511f072 100644 --- a/src/python/pants/build_graph/intermediate_target_factory.py +++ b/src/python/pants/build_graph/intermediate_target_factory.py @@ -4,6 +4,7 @@ from __future__ import absolute_import, division, print_function, unicode_literals +from abc import ABC from builtins import str from hashlib import sha1 @@ -11,7 +12,6 @@ from pants.base.exceptions import TargetDefinitionException from pants.build_graph.address import Address -from pants.util.meta import AbstractClass def hash_target(address, suffix): @@ -21,7 +21,7 @@ def hash_target(address, suffix): return hasher.hexdigest() if PY3 else hasher.hexdigest().decode('utf-8') -class IntermediateTargetFactoryBase(AbstractClass): +class IntermediateTargetFactoryBase(ABC): """Convenience factory which constructs an intermediate target with the appropriate attributes.""" class ExpectedAddressError(TargetDefinitionException): diff --git a/src/python/pants/build_graph/mirrored_target_option_mixin.py b/src/python/pants/build_graph/mirrored_target_option_mixin.py index febde9f9658..9bbee7d6fd0 100644 --- a/src/python/pants/build_graph/mirrored_target_option_mixin.py +++ b/src/python/pants/build_graph/mirrored_target_option_mixin.py @@ -4,12 +4,11 @@ from __future__ import absolute_import, division, print_function, unicode_literals -from abc import abstractproperty +from abc import ABC, abstractproperty from future.utils import text_type from pants.util.memo import memoized_property -from pants.util.meta import AbstractClass from pants.util.objects import datatype @@ -55,7 +54,7 @@ def get_mirrored_scalar_option_value(self, target): return self.option_value -class MirroredTargetOptionMixin(AbstractClass): +class MirroredTargetOptionMixin(ABC): """Get option values which may be set in this subsystem or in a Target's keyword argument. A subsystem or task mixing in this class may set e.g.: diff --git a/src/python/pants/cache/BUILD b/src/python/pants/cache/BUILD index 3e9417a5a12..b9b290a4aaf 100644 --- a/src/python/pants/cache/BUILD +++ b/src/python/pants/cache/BUILD @@ -12,6 +12,5 @@ python_library( 'src/python/pants/util:contextutil', 'src/python/pants/util:dirutil', 'src/python/pants/util:memo', - 'src/python/pants/util:meta', ] ) diff --git a/src/python/pants/cache/resolver.py b/src/python/pants/cache/resolver.py index 72f5cda5874..5e5ab0171c1 100644 --- a/src/python/pants/cache/resolver.py +++ b/src/python/pants/cache/resolver.py @@ -6,19 +6,18 @@ import json import logging -from abc import abstractmethod +from abc import ABC, abstractmethod from builtins import object, str import requests from pants.base.validation import assert_list -from pants.util.meta import AbstractClass logger = logging.getLogger(__name__) -class Resolver(AbstractClass): +class Resolver(ABC): """An abstract class base for resolving service urls. :API: public diff --git a/src/python/pants/engine/BUILD b/src/python/pants/engine/BUILD index e6ed9eba177..b958b30d0c9 100644 --- a/src/python/pants/engine/BUILD +++ b/src/python/pants/engine/BUILD @@ -18,7 +18,6 @@ python_library( 'src/python/pants/base:exceptions', 'src/python/pants/base:workunit', 'src/python/pants/goal', - 'src/python/pants/util:meta', ], ) @@ -56,7 +55,6 @@ python_library( ':selectors', 'src/python/pants/base:project_tree', 'src/python/pants/option', - 'src/python/pants/util:meta', 'src/python/pants/util:objects', ] ) @@ -135,7 +133,6 @@ python_library( sources=['objects.py'], dependencies=[ '3rdparty/python:future', - 'src/python/pants/util:meta', 'src/python/pants/util:memo', 'src/python/pants/util:objects', ] @@ -174,7 +171,6 @@ python_library( dependencies=[ '3rdparty/python:future', '3rdparty/python:six', - 'src/python/pants/util:meta', 'src/python/pants/util:objects', ] ) diff --git a/src/python/pants/engine/goal.py b/src/python/pants/engine/goal.py index 71e794fb19c..3a448af2ce1 100644 --- a/src/python/pants/engine/goal.py +++ b/src/python/pants/engine/goal.py @@ -4,7 +4,7 @@ from __future__ import absolute_import, division, print_function, unicode_literals -from abc import abstractmethod +from abc import ABCMeta, abstractmethod from contextlib import contextmanager from pants.cache.cache_setup import CacheSetup @@ -12,13 +12,13 @@ from pants.option.scope import ScopeInfo from pants.subsystem.subsystem_client_mixin import SubsystemClientMixin from pants.util.memo import memoized_classproperty -from pants.util.meta import AbstractClass, classproperty +from pants.util.meta import classproperty from pants.util.objects import datatype -class Goal(datatype([('exit_code', int)]), AbstractClass): +class Goal(datatype([('exit_code', int)]), metaclass=ABCMeta): """The named product of a `@console_rule`. - + This abstract class should be subclassed and given a `Goal.name` that it will be referred to by when invoked from the command line. The `Goal.name` also acts as the options_scope for the `Goal`. diff --git a/src/python/pants/engine/legacy/structs.py b/src/python/pants/engine/legacy/structs.py index 9be48d8fb32..4c046d4b505 100644 --- a/src/python/pants/engine/legacy/structs.py +++ b/src/python/pants/engine/legacy/structs.py @@ -6,7 +6,7 @@ import logging import os.path -from abc import abstractproperty +from abc import ABCMeta, abstractproperty from builtins import object, str from six import string_types @@ -20,7 +20,7 @@ from pants.source import wrapped_globs from pants.util.collections_abc_backport import MutableSequence, MutableSet from pants.util.contextutil import exception_logging -from pants.util.meta import AbstractClass, classproperty +from pants.util.meta import classproperty from pants.util.objects import Exactly, SubclassesOf, datatype @@ -299,7 +299,7 @@ def get_sources(self): return GlobsWithConjunction.for_literal_files(['register.py'], self.address.spec_path) -class BaseGlobs(Locatable, AbstractClass): +class BaseGlobs(Locatable, metaclass=ABCMeta): """An adaptor class to allow BUILD file parsing from ContextAwareObjectFactories.""" @staticmethod diff --git a/src/python/pants/engine/legacy_engine.py b/src/python/pants/engine/legacy_engine.py index 072d89d2dec..af7903c15e6 100644 --- a/src/python/pants/engine/legacy_engine.py +++ b/src/python/pants/engine/legacy_engine.py @@ -4,14 +4,13 @@ from __future__ import absolute_import, division, print_function, unicode_literals -from abc import abstractmethod +from abc import ABC, abstractmethod from builtins import str from pants.base.exceptions import TaskError -from pants.util.meta import AbstractClass -class Engine(AbstractClass): +class Engine(ABC): """An engine for running a pants command line.""" def execute(self, context, goals): diff --git a/src/python/pants/engine/nodes.py b/src/python/pants/engine/nodes.py index e8a87c20612..6e26fe2745e 100644 --- a/src/python/pants/engine/nodes.py +++ b/src/python/pants/engine/nodes.py @@ -5,8 +5,8 @@ from __future__ import absolute_import, division, print_function, unicode_literals import logging +from abc import ABC -from pants.util.meta import AbstractClass from pants.util.objects import datatype @@ -18,7 +18,7 @@ def _satisfied_by(t, o): return t.satisfied_by(o) -class State(AbstractClass): +class State(ABC): @classmethod def raise_unrecognized(cls, state): raise ValueError('Unrecognized Node State: {}'.format(state)) diff --git a/src/python/pants/engine/objects.py b/src/python/pants/engine/objects.py index 7dc958229c9..66f2670f46e 100644 --- a/src/python/pants/engine/objects.py +++ b/src/python/pants/engine/objects.py @@ -6,14 +6,13 @@ import inspect import sys -from abc import abstractmethod, abstractproperty +from abc import ABC, abstractmethod, abstractproperty from builtins import object from collections import namedtuple from future.utils import PY2 from pants.util.memo import memoized_classmethod -from pants.util.meta import AbstractClass from pants.util.objects import Exactly, TypedCollection, datatype @@ -22,7 +21,7 @@ class SerializationError(Exception): # TODO: Likely no longer necessary, due to the laziness of the product graph. -class Resolvable(AbstractClass): +class Resolvable(ABC): """Represents a resolvable object.""" @abstractproperty @@ -39,7 +38,7 @@ def _unpickle_serializable(serializable_class, kwargs): return serializable_class(**kwargs) -class Locatable(AbstractClass): +class Locatable(ABC): """Marks a class whose constructor should receive its spec_path relative to the build root. Locatable objects will be passed a `spec_path` constructor kwarg that indicates where they @@ -64,7 +63,7 @@ def create(cls, serializable_instance): args=(type(serializable_instance), serializable_instance._asdict())) -class Serializable(AbstractClass): +class Serializable(ABC): """Marks a class that can be serialized into and reconstituted from python builtin values. Also provides support for the pickling protocol out of the box. @@ -118,7 +117,7 @@ def __reduce__(self): return SerializablePickle.create(self) -class SerializableFactory(AbstractClass): +class SerializableFactory(ABC): """Creates :class:`Serializable` objects.""" @abstractmethod @@ -143,7 +142,7 @@ def __init__(self, identifier, message): .format(id=identifier, msg=message)) -class Validatable(AbstractClass): +class Validatable(ABC): """Marks a class whose instances should validated post-construction.""" @abstractmethod diff --git a/src/python/pants/engine/parser.py b/src/python/pants/engine/parser.py index ab025ec067d..608053ecc6c 100644 --- a/src/python/pants/engine/parser.py +++ b/src/python/pants/engine/parser.py @@ -4,9 +4,8 @@ from __future__ import absolute_import, division, print_function, unicode_literals -from abc import abstractmethod +from abc import ABC, abstractmethod -from pants.util.meta import AbstractClass from pants.util.objects import datatype @@ -28,7 +27,7 @@ class HydratedStruct(datatype(['value'])): """ -class Parser(AbstractClass): +class Parser(ABC): @abstractmethod def parse(self, filepath, filecontent): diff --git a/src/python/pants/engine/rules.py b/src/python/pants/engine/rules.py index 413e6f75345..7432cea6fa7 100644 --- a/src/python/pants/engine/rules.py +++ b/src/python/pants/engine/rules.py @@ -9,7 +9,7 @@ import itertools import logging import sys -from abc import abstractproperty +from abc import ABC, abstractproperty import asttokens from twitter.common.collections import OrderedSet @@ -19,7 +19,6 @@ from pants.util.collections import assert_single_element from pants.util.collections_abc_backport import Iterable, OrderedDict from pants.util.memo import memoized -from pants.util.meta import AbstractClass from pants.util.objects import SubclassesOf, TypedCollection, datatype @@ -321,7 +320,7 @@ def __new__(cls, union_base, union_member): return super(UnionRule, cls).__new__(cls, union_base, union_member) -class Rule(AbstractClass): +class Rule(ABC): """Rules declare how to produce products for the product graph. A rule describes what dependencies must be provided to produce a particular product. They also act diff --git a/src/python/pants/fs/BUILD b/src/python/pants/fs/BUILD index f491bed04f1..47ec3047954 100644 --- a/src/python/pants/fs/BUILD +++ b/src/python/pants/fs/BUILD @@ -6,7 +6,6 @@ python_library( 'src/python/pants/util:collections_abc_backport', 'src/python/pants/util:contextutil', 'src/python/pants/util:dirutil', - 'src/python/pants/util:meta', 'src/python/pants/util:process_handler', 'src/python/pants/util:strutil', ] diff --git a/src/python/pants/fs/archive.py b/src/python/pants/fs/archive.py index 1625ccffa6a..0c2f048ca08 100644 --- a/src/python/pants/fs/archive.py +++ b/src/python/pants/fs/archive.py @@ -6,7 +6,7 @@ import os import sys -from abc import abstractmethod +from abc import ABC, abstractmethod from contextlib import contextmanager from zipfile import ZIP_DEFLATED @@ -15,7 +15,6 @@ from pants.util.collections_abc_backport import OrderedDict from pants.util.contextutil import open_tar, open_zip, temporary_dir from pants.util.dirutil import is_executable, safe_concurrent_rename, safe_walk -from pants.util.meta import AbstractClass from pants.util.process_handler import subprocess from pants.util.strutil import ensure_text @@ -23,7 +22,7 @@ """Support for wholesale archive creation and extraction in a uniform API across archive types.""" -class Archiver(AbstractClass): +class Archiver(ABC): def extract(self, path, outdir, concurrency_safe=False, **kwargs): """Extracts an archive's contents to the specified outdir with an optional filter. diff --git a/src/python/pants/goal/BUILD b/src/python/pants/goal/BUILD index b2d2182fc62..32e1cbd0c80 100644 --- a/src/python/pants/goal/BUILD +++ b/src/python/pants/goal/BUILD @@ -116,6 +116,5 @@ python_library( dependencies = [ 'src/python/pants/base:build_environment', 'src/python/pants/scm', - 'src/python/pants/util:meta', ], ) diff --git a/src/python/pants/goal/workspace.py b/src/python/pants/goal/workspace.py index 2071f5ba871..9697f3c645f 100644 --- a/src/python/pants/goal/workspace.py +++ b/src/python/pants/goal/workspace.py @@ -4,14 +4,13 @@ from __future__ import absolute_import, division, print_function, unicode_literals -from abc import abstractmethod +from abc import ABC, abstractmethod from pants.base.build_environment import get_buildroot from pants.scm.scm import Scm -from pants.util.meta import AbstractClass -class Workspace(AbstractClass): +class Workspace(ABC): """Tracks the state of the current workspace.""" class WorkspaceError(Exception): diff --git a/src/python/pants/invalidation/BUILD b/src/python/pants/invalidation/BUILD index c5885051bf6..be81454bca3 100644 --- a/src/python/pants/invalidation/BUILD +++ b/src/python/pants/invalidation/BUILD @@ -11,6 +11,5 @@ python_library( 'src/python/pants/subsystem', 'src/python/pants/util:dirutil', 'src/python/pants/util:memo', - 'src/python/pants/util:meta', ], ) diff --git a/src/python/pants/invalidation/build_invalidator.py b/src/python/pants/invalidation/build_invalidator.py index 6d63f730881..3526fe39e97 100644 --- a/src/python/pants/invalidation/build_invalidator.py +++ b/src/python/pants/invalidation/build_invalidator.py @@ -7,7 +7,7 @@ import errno import hashlib import os -from abc import abstractmethod +from abc import ABC, abstractmethod from builtins import object, open from collections import namedtuple @@ -16,7 +16,6 @@ from pants.fs.fs import safe_filename from pants.subsystem.subsystem import Subsystem from pants.util.dirutil import safe_mkdir -from pants.util.meta import AbstractClass # Bump this to invalidate all existing keys in artifact caches across all pants deployments in the @@ -68,7 +67,7 @@ def cacheable(self): return self.hash != self._UNCACHEABLE_HASH -class CacheKeyGeneratorInterface(AbstractClass): +class CacheKeyGeneratorInterface(ABC): """Generates cache keys for versions of target sets.""" @abstractmethod diff --git a/src/python/pants/java/BUILD b/src/python/pants/java/BUILD index 5b7f6d0a9a9..d71e0e3e84c 100644 --- a/src/python/pants/java/BUILD +++ b/src/python/pants/java/BUILD @@ -11,7 +11,6 @@ python_library( 'src/python/pants/base:build_environment', 'src/python/pants/util:contextutil', 'src/python/pants/util:dirutil', - 'src/python/pants/util:meta', 'src/python/pants/util:process_handler', ] ) @@ -45,7 +44,6 @@ python_library( dependencies = [ '3rdparty/python:future', '3rdparty/python:six', - 'src/python/pants/util:meta', 'src/python/pants/util:objects', 'src/python/pants/util:osutil', ] diff --git a/src/python/pants/java/distribution/distribution.py b/src/python/pants/java/distribution/distribution.py index f9073efe3b5..ab1ad7279c7 100644 --- a/src/python/pants/java/distribution/distribution.py +++ b/src/python/pants/java/distribution/distribution.py @@ -9,7 +9,7 @@ import os import pkgutil import plistlib -from abc import abstractproperty +from abc import ABC, abstractproperty from builtins import object, open, str from collections import namedtuple from contextlib import contextmanager @@ -22,7 +22,6 @@ from pants.subsystem.subsystem import Subsystem from pants.util.contextutil import temporary_dir from pants.util.memo import memoized_method, memoized_property -from pants.util.meta import AbstractClass from pants.util.osutil import OS_ALIASES, normalize_os_name from pants.util.process_handler import subprocess @@ -283,7 +282,7 @@ def __repr__(self): self._bin_path, self._minimum_version, self._maximum_version, self._jdk)) -class _DistributionEnvironment(AbstractClass): +class _DistributionEnvironment(ABC): class Location(namedtuple('Location', ['home_path', 'bin_path'])): """Represents the location of a java distribution.""" diff --git a/src/python/pants/java/executor.py b/src/python/pants/java/executor.py index 67c38c14f86..618ba2d9e2d 100644 --- a/src/python/pants/java/executor.py +++ b/src/python/pants/java/executor.py @@ -7,7 +7,7 @@ import logging import os import sys -from abc import abstractmethod, abstractproperty +from abc import ABC, abstractmethod, abstractproperty from builtins import object from contextlib import contextmanager @@ -15,14 +15,13 @@ from twitter.common.collections import maybe_list from pants.util.contextutil import environment_as -from pants.util.meta import AbstractClass from pants.util.process_handler import subprocess logger = logging.getLogger(__name__) -class Executor(AbstractClass): +class Executor(ABC): """Executes java programs. :API: public diff --git a/src/python/pants/java/nailgun_protocol.py b/src/python/pants/java/nailgun_protocol.py index c00da183205..ca69f27c6bd 100644 --- a/src/python/pants/java/nailgun_protocol.py +++ b/src/python/pants/java/nailgun_protocol.py @@ -10,11 +10,10 @@ import struct import threading import time -from abc import abstractmethod +from abc import ABC, abstractmethod from builtins import bytes, object, str, zip from contextlib import contextmanager -from pants.util.meta import AbstractClass from pants.util.objects import datatype from pants.util.osutil import IntegerForPid @@ -239,7 +238,7 @@ def _set_socket_timeout(cls, sock, timeout=None): class TimeoutOptions(datatype([('start_time', float), ('interval', float)])): pass - class TimeoutProvider(AbstractClass): + class TimeoutProvider(ABC): @abstractmethod def maybe_timeout_options(self): diff --git a/src/python/pants/net/BUILD b/src/python/pants/net/BUILD index 6be20933e6f..3a24839b97d 100644 --- a/src/python/pants/net/BUILD +++ b/src/python/pants/net/BUILD @@ -9,6 +9,5 @@ python_library( '3rdparty/python:pyopenssl', '3rdparty/python:six', 'src/python/pants/util:dirutil', - 'src/python/pants/util:meta', ], ) diff --git a/src/python/pants/net/http/fetcher.py b/src/python/pants/net/http/fetcher.py index ae326afdae4..bc37d521730 100644 --- a/src/python/pants/net/http/fetcher.py +++ b/src/python/pants/net/http/fetcher.py @@ -10,7 +10,7 @@ import sys import tempfile import time -from abc import abstractmethod, abstractproperty +from abc import ABC, abstractmethod, abstractproperty from builtins import object, open, str from contextlib import closing, contextmanager @@ -19,7 +19,6 @@ from future.utils import PY3 from pants.util.dirutil import safe_open -from pants.util.meta import AbstractClass from pants.util.strutil import strip_prefix @@ -210,7 +209,7 @@ def __init__(self, root_dir, requests_api=None): self._root_dir = root_dir self._requests = requests_api or requests - class _Response(AbstractClass): + class _Response(ABC): """Abstracts a fetch response.""" @abstractproperty diff --git a/src/python/pants/option/arg_splitter.py b/src/python/pants/option/arg_splitter.py index bdd873b18fe..9868bf859a7 100644 --- a/src/python/pants/option/arg_splitter.py +++ b/src/python/pants/option/arg_splitter.py @@ -6,13 +6,13 @@ import os import sys +from abc import ABC from builtins import object from collections import namedtuple from twitter.common.collections import OrderedSet from pants.option.scope import GLOBAL_SCOPE, GLOBAL_SCOPE_CONFIG_SECTION, ScopeInfo -from pants.util.meta import AbstractClass # TODO: Switch all clients to reference pants.option.scope directly. @@ -38,7 +38,7 @@ class SplitArgs(namedtuple('SplitArgs', """ -class HelpRequest(AbstractClass): +class HelpRequest(ABC): """Represents an implicit or explicit request for help by the user.""" diff --git a/src/python/pants/option/config.py b/src/python/pants/option/config.py index 3b4c8e45efd..91e19c6ee43 100644 --- a/src/python/pants/option/config.py +++ b/src/python/pants/option/config.py @@ -8,6 +8,7 @@ import io import itertools import os +from abc import ABC from builtins import open from contextlib import contextmanager from hashlib import sha1 @@ -17,12 +18,11 @@ from pants.base.build_environment import get_buildroot, get_pants_cachedir, get_pants_configdir from pants.util.eval import parse_expression -from pants.util.meta import AbstractClass from pants.util.objects import datatype from pants.util.py2_compat import configparser -class Config(AbstractClass): +class Config(ABC): """Encapsulates ini-style config file loading and access. Supports recursive variable substitution using standard python format strings. E.g., diff --git a/src/python/pants/option/optionable.py b/src/python/pants/option/optionable.py index 3b239c476d7..62834f11579 100644 --- a/src/python/pants/option/optionable.py +++ b/src/python/pants/option/optionable.py @@ -6,13 +6,13 @@ import functools import re -from abc import abstractproperty +from abc import ABC, ABCMeta, abstractproperty from builtins import str from pants.engine.selectors import Get from pants.option.errors import OptionsError from pants.option.scope import Scope, ScopedOptions, ScopeInfo -from pants.util.meta import AbstractClass, classproperty +from pants.util.meta import classproperty def _construct_optionable(optionable_factory): @@ -21,7 +21,7 @@ def _construct_optionable(optionable_factory): yield optionable_factory.optionable_cls(scope, scoped_options.options) -class OptionableFactory(AbstractClass): +class OptionableFactory(ABC): """A mixin that provides a method that returns an @rule to construct subclasses of Optionable. Optionable subclasses constructed in this manner must have a particular constructor shape, which is @@ -54,7 +54,7 @@ def signature(cls): ) -class Optionable(OptionableFactory, AbstractClass): +class Optionable(OptionableFactory, metaclass=ABCMeta): """A mixin for classes that can register options on some scope.""" # Subclasses must override. diff --git a/src/python/pants/pantsd/service/BUILD b/src/python/pants/pantsd/service/BUILD index 1d2039ecab4..c062472ebfd 100644 --- a/src/python/pants/pantsd/service/BUILD +++ b/src/python/pants/pantsd/service/BUILD @@ -5,7 +5,7 @@ python_library( name = 'pants_service', sources = ['pants_service.py'], dependencies = [ - 'src/python/pants/util:meta' + 'src/python/pants/util:objects' ] ) diff --git a/src/python/pants/pantsd/service/pants_service.py b/src/python/pants/pantsd/service/pants_service.py index 5a797e11515..a962559f607 100644 --- a/src/python/pants/pantsd/service/pants_service.py +++ b/src/python/pants/pantsd/service/pants_service.py @@ -6,9 +6,8 @@ import threading import time -from abc import abstractmethod +from abc import ABC, abstractmethod -from pants.util.meta import AbstractClass from pants.util.objects import datatype @@ -33,7 +32,7 @@ def __new__(cls, services=None, port_map=None, lifecycle_lock=None): return super(PantsServices, cls).__new__(cls, services, port_map, lifecycle_lock) -class PantsService(AbstractClass): +class PantsService(ABC): """Pants daemon service base class. The service lifecycle is made up of states described in the _ServiceState class, and controlled diff --git a/src/python/pants/scm/BUILD b/src/python/pants/scm/BUILD index 2d1ed4870bd..5519f87e461 100644 --- a/src/python/pants/scm/BUILD +++ b/src/python/pants/scm/BUILD @@ -5,7 +5,6 @@ python_library( sources = ['scm.py'], dependencies = [ 'src/python/pants/util:contextutil', - 'src/python/pants/util:meta', ], ) diff --git a/src/python/pants/scm/scm.py b/src/python/pants/scm/scm.py index 82daa2bbc50..74213abf4bc 100644 --- a/src/python/pants/scm/scm.py +++ b/src/python/pants/scm/scm.py @@ -4,12 +4,10 @@ from __future__ import absolute_import, division, print_function, unicode_literals -from abc import abstractmethod, abstractproperty +from abc import ABC, abstractmethod, abstractproperty -from pants.util.meta import AbstractClass - -class Scm(AbstractClass): +class Scm(ABC): """Abstracts high-level scm operations needed by pants core and pants tasks. :API: public diff --git a/src/python/pants/source/wrapped_globs.py b/src/python/pants/source/wrapped_globs.py index 1deab4c9dda..d7646552e70 100644 --- a/src/python/pants/source/wrapped_globs.py +++ b/src/python/pants/source/wrapped_globs.py @@ -5,7 +5,7 @@ from __future__ import absolute_import, division, print_function, unicode_literals import os -from abc import abstractmethod, abstractproperty +from abc import ABC, abstractmethod, abstractproperty from builtins import open from hashlib import sha1 @@ -16,10 +16,9 @@ from pants.engine.fs import EMPTY_SNAPSHOT from pants.util.dirutil import fast_relpath, fast_relpath_optional from pants.util.memo import memoized_property -from pants.util.meta import AbstractClass -class FilesetWithSpec(AbstractClass): +class FilesetWithSpec(ABC): """A set of files that keeps track of how we got it.""" @staticmethod @@ -152,7 +151,7 @@ def matches(self, path_from_buildroot): return any(path_from_buildroot == path_in_spec for path_in_spec in self.paths_from_buildroot_iter()) -class FilesetRelPathWrapper(AbstractClass): +class FilesetRelPathWrapper(ABC): KNOWN_PARAMETERS = frozenset({'exclude', 'follow_links'}) @abstractproperty diff --git a/src/python/pants/task/task.py b/src/python/pants/task/task.py index f397c91b124..43cadc06e50 100644 --- a/src/python/pants/task/task.py +++ b/src/python/pants/task/task.py @@ -6,7 +6,7 @@ import os import sys -from abc import abstractmethod +from abc import ABCMeta, abstractmethod from builtins import filter, map, object, set, str, zip from contextlib import contextmanager from hashlib import sha1 @@ -30,10 +30,10 @@ from pants.subsystem.subsystem_client_mixin import SubsystemClientMixin from pants.util.dirutil import safe_mkdir, safe_rm_oldest_items_in_dir from pants.util.memo import memoized_method, memoized_property -from pants.util.meta import AbstractClass, classproperty +from pants.util.meta import classproperty -class TaskBase(SubsystemClientMixin, Optionable, AbstractClass): +class TaskBase(SubsystemClientMixin, Optionable, metaclass=ABCMeta): """Defines a lifecycle that prepares a task for execution and provides the base machinery needed to execute it. diff --git a/src/python/pants/task/unpack_remote_sources_base.py b/src/python/pants/task/unpack_remote_sources_base.py index 5d0dbaa8ad0..3b525880b36 100644 --- a/src/python/pants/task/unpack_remote_sources_base.py +++ b/src/python/pants/task/unpack_remote_sources_base.py @@ -7,7 +7,7 @@ import logging import os import re -from abc import abstractmethod +from abc import ABCMeta, abstractmethod from future.utils import text_type from twitter.common.dirutil.fileset import fnmatch_translate_extended @@ -15,7 +15,7 @@ from pants.base.build_environment import get_buildroot from pants.base.exceptions import TaskError from pants.task.task import Task -from pants.util.meta import AbstractClass, classproperty +from pants.util.meta import classproperty from pants.util.objects import datatype @@ -31,7 +31,7 @@ def __new__(cls, found_files, rel_unpack_dir): text_type(rel_unpack_dir)) -class UnpackRemoteSourcesBase(Task, AbstractClass): +class UnpackRemoteSourcesBase(Task, metaclass=ABCMeta): @property def cache_target_dirs(cls): diff --git a/src/python/pants/util/BUILD b/src/python/pants/util/BUILD index 2d7f9deb913..4c3796a1fb9 100644 --- a/src/python/pants/util/BUILD +++ b/src/python/pants/util/BUILD @@ -136,7 +136,6 @@ python_library( dependencies= [ '3rdparty/python:future', '3rdparty/python:subprocess32', - ':meta', ] ) diff --git a/src/python/pants/util/meta.py b/src/python/pants/util/meta.py index af84d5111e6..8a79ef4b4cc 100644 --- a/src/python/pants/util/meta.py +++ b/src/python/pants/util/meta.py @@ -4,7 +4,7 @@ from __future__ import absolute_import, division, print_function, unicode_literals -from abc import ABCMeta, abstractproperty +from abc import abstractproperty from builtins import object @@ -111,10 +111,3 @@ def staticproperty(func): Singleton = SingletonMetaclass(u'Singleton', (object,), {}) except TypeError: # Python2 Singleton = SingletonMetaclass(b'Singleton', (object,), {}) - - -# Abstract base classes w/o __metaclass__ or meta =, just extend AbstractClass. -try: # Python3 - AbstractClass = ABCMeta(u'AbstractClass', (object,), {}) -except TypeError: # Python2 - AbstractClass = ABCMeta(b'AbstractClass', (object,), {}) diff --git a/src/python/pants/util/objects.py b/src/python/pants/util/objects.py index c57ff45a90a..75c34589f7a 100644 --- a/src/python/pants/util/objects.py +++ b/src/python/pants/util/objects.py @@ -5,7 +5,7 @@ from __future__ import absolute_import, division, print_function, unicode_literals import re -from abc import abstractmethod, abstractproperty +from abc import ABC, abstractmethod, abstractproperty from builtins import zip from future.utils import binary_type, text_type @@ -13,7 +13,7 @@ from pants.util.collections_abc_backport import Iterable, OrderedDict, namedtuple from pants.util.memo import memoized_classproperty -from pants.util.meta import AbstractClass, classproperty +from pants.util.meta import classproperty from pants.util.strutil import pluralize @@ -32,7 +32,7 @@ class TypedDatatypeInstanceConstructionError(TypeCheckError): """Raised when a datatype()'s fields fail a type check upon construction.""" -class DatatypeMixin(AbstractClass): +class DatatypeMixin(ABC): """Decouple datatype logic from the way it's created to ease migration to python 3 dataclasses.""" @classproperty @@ -246,7 +246,7 @@ class EnumVariantSelectionError(TypeCheckError): # TODO: look into merging this with pants.util.meta.Singleton! -class ChoicesMixin(AbstractClass): +class ChoicesMixin(ABC): """A mixin which declares that the type has a fixed set of possible instances.""" @classproperty @@ -401,7 +401,7 @@ class TypeConstraintError(TypeError): """Indicates a :class:`TypeConstraint` violation.""" -class TypeConstraint(AbstractClass): +class TypeConstraint(ABC): """Represents a type constraint. Not intended for direct use; instead, use one of :class:`SuperclassesOf`, :class:`Exactly` or diff --git a/src/python/pants/util/process_handler.py b/src/python/pants/util/process_handler.py index d1ee28dffad..128b37248ef 100644 --- a/src/python/pants/util/process_handler.py +++ b/src/python/pants/util/process_handler.py @@ -8,12 +8,10 @@ import multiprocessing import os import sys -from abc import abstractmethod +from abc import ABC, abstractmethod from future.utils import PY2, PY3 -from pants.util.meta import AbstractClass - # Expose subprocess with python 3.2+ capabilities (namely timeouts) and bugfixes from this module. # NB: As recommended here: https://github.com/google/python-subprocess32/blob/master/README.md @@ -26,7 +24,7 @@ subprocess = subprocess3 -class ProcessHandler(AbstractClass): +class ProcessHandler(ABC): """An abstraction of process handling calls using the same interface as subprocess(32).Popen. See SubprocessProcessHandler below for an example. diff --git a/tests/python/pants_test/BUILD b/tests/python/pants_test/BUILD index 661e867d130..7c49be61f56 100644 --- a/tests/python/pants_test/BUILD +++ b/tests/python/pants_test/BUILD @@ -73,6 +73,7 @@ python_library( 'src/python/pants/task', 'src/python/pants/util:dirutil', 'src/python/pants/util:memo', + 'src/python/pants/util:meta', 'tests/python/pants_test/base:context_utils', 'tests/python/pants_test/engine:util', 'tests/python/pants_test/option/util', diff --git a/tests/python/pants_test/backend/project_info/tasks/test_filedeps.py b/tests/python/pants_test/backend/project_info/tasks/test_filedeps.py index bed0dc37b78..90016613afa 100644 --- a/tests/python/pants_test/backend/project_info/tasks/test_filedeps.py +++ b/tests/python/pants_test/backend/project_info/tasks/test_filedeps.py @@ -13,10 +13,10 @@ from pants.backend.project_info.tasks.filedeps import FileDeps from pants.build_graph.register import build_file_aliases as register_core from pants_test.task_test_base import ConsoleTaskTestBase -from pants_test.test_base import TestGenerator +from pants_test.test_base import AbstractTestGenerator -class FileDepsTest(ConsoleTaskTestBase, TestGenerator): +class FileDepsTest(ConsoleTaskTestBase, AbstractTestGenerator): @classmethod def alias_groups(cls): diff --git a/tests/python/pants_test/base/BUILD b/tests/python/pants_test/base/BUILD index 7e0da587647..4be05e85214 100644 --- a/tests/python/pants_test/base/BUILD +++ b/tests/python/pants_test/base/BUILD @@ -157,7 +157,6 @@ python_library( sources = ['project_tree_test_base.py'], dependencies = [ 'src/python/pants/util:dirutil', - 'src/python/pants/util:meta', ] ) diff --git a/tests/python/pants_test/base/project_tree_test_base.py b/tests/python/pants_test/base/project_tree_test_base.py index b2bf4d69fe9..f298e3dae8b 100644 --- a/tests/python/pants_test/base/project_tree_test_base.py +++ b/tests/python/pants_test/base/project_tree_test_base.py @@ -7,13 +7,12 @@ import os import shutil import tempfile -from abc import abstractmethod +from abc import ABC, abstractmethod from pants.util.dirutil import safe_mkdir, touch -from pants.util.meta import AbstractClass -class ProjectTreeTestBase(AbstractClass): +class ProjectTreeTestBase(ABC): @abstractmethod def mk_project_tree(self, build_root, ignore_patterns=[]): diff --git a/tests/python/pants_test/engine/legacy/test_changed_integration.py b/tests/python/pants_test/engine/legacy/test_changed_integration.py index 2d673460a14..182d52a2689 100644 --- a/tests/python/pants_test/engine/legacy/test_changed_integration.py +++ b/tests/python/pants_test/engine/legacy/test_changed_integration.py @@ -14,7 +14,7 @@ from pants.util.contextutil import environment_as, temporary_dir from pants.util.dirutil import safe_delete, safe_mkdir, safe_open, touch from pants_test.pants_run_integration_test import PantsRunIntegrationTest, ensure_daemon -from pants_test.test_base import TestGenerator +from pants_test.test_base import AbstractTestGenerator from pants_test.testutils.git_util import initialize_repo from pants_test.testutils.py2_compat import assertRegex @@ -191,7 +191,7 @@ class HelloWorld { yield worktree -class ChangedIntegrationTest(PantsRunIntegrationTest, TestGenerator): +class ChangedIntegrationTest(PantsRunIntegrationTest, AbstractTestGenerator): TEST_MAPPING = { # A `jvm_binary` with `source='file.name'`. diff --git a/tests/python/pants_test/engine/test_fs.py b/tests/python/pants_test/engine/test_fs.py index 33fc1bdc330..7f7c0afcaab 100644 --- a/tests/python/pants_test/engine/test_fs.py +++ b/tests/python/pants_test/engine/test_fs.py @@ -9,10 +9,12 @@ import os import tarfile import unittest +from abc import ABCMeta from builtins import open, str from contextlib import contextmanager +from http.server import BaseHTTPRequestHandler -from future.utils import PY2, text_type +from future.utils import text_type from pants.engine.fs import (EMPTY_DIRECTORY_DIGEST, Digest, DirectoriesToMerge, DirectoryToMaterialize, DirectoryWithPrefixToStrip, FilesContent, @@ -22,18 +24,11 @@ from pants.util.collections import assert_single_element from pants.util.contextutil import http_server, temporary_dir from pants.util.dirutil import relative_symlink, safe_file_dump -from pants.util.meta import AbstractClass from pants_test.engine.scheduler_test_base import SchedulerTestBase from pants_test.test_base import TestBase -if PY2: - from BaseHTTPServer import BaseHTTPRequestHandler -else: - from http.server import BaseHTTPRequestHandler - - -class FSTest(TestBase, SchedulerTestBase, AbstractClass): +class FSTest(TestBase, SchedulerTestBase, metaclass=ABCMeta): _original_src = os.path.join(os.path.dirname(__file__), 'examples/fs_test/fs_test.tar') diff --git a/tests/python/pants_test/test_base.py b/tests/python/pants_test/test_base.py index cbba5111392..15813ed5f0b 100644 --- a/tests/python/pants_test/test_base.py +++ b/tests/python/pants_test/test_base.py @@ -9,6 +9,7 @@ import os import unittest import warnings +from abc import ABC, ABCMeta, abstractmethod from builtins import object, open, str from collections import defaultdict from contextlib import contextmanager @@ -40,17 +41,18 @@ from pants.util.dirutil import (recursive_dirname, relative_symlink, safe_file_dump, safe_mkdir, safe_mkdtemp, safe_open, safe_rmtree) from pants.util.memo import memoized_method -from pants.util.meta import AbstractClass, classproperty +from pants.util.meta import classproperty from pants_test.base.context_utils import create_context_from_options from pants_test.engine.util import init_native from pants_test.option.util.fakes import create_options_for_optionables from pants_test.subsystem import subsystem_util -class TestGenerator(object): +class AbstractTestGenerator(ABC): """A mixin that facilitates test generation at runtime.""" @classmethod + @abstractmethod def generate_tests(cls): """Generate tests for a given class. @@ -62,9 +64,6 @@ class ThingTest(TestGenerator): ThingTest.generate_tests() """ - # This would be an @abstractmethod, but making TestGenerator extend AbstractClass causes an - # error as it gets instantiated directly somehow in testing. - raise NotImplementedError() @classmethod def add_test(cls, method_name, method): @@ -81,7 +80,7 @@ def add_test(cls, method_name, method): setattr(cls, method_name, method) -class TestBase(unittest.TestCase, AbstractClass): +class TestBase(unittest.TestCase, metaclass=ABCMeta): """A baseclass useful for tests requiring a temporary buildroot. :API: public diff --git a/tests/python/pants_test/util/test_meta.py b/tests/python/pants_test/util/test_meta.py index f1ca98a6eaa..4063dcba5d7 100644 --- a/tests/python/pants_test/util/test_meta.py +++ b/tests/python/pants_test/util/test_meta.py @@ -4,16 +4,16 @@ from __future__ import absolute_import, division, print_function, unicode_literals -from abc import abstractmethod, abstractproperty +from abc import ABC, abstractmethod, abstractproperty from builtins import object -from pants.util.meta import AbstractClass, Singleton, classproperty, staticproperty +from pants.util.meta import Singleton, classproperty, staticproperty from pants_test.test_base import TestBase class AbstractClassTest(TestBase): def test_abstract_property(self): - class AbstractProperty(AbstractClass): + class AbstractProperty(ABC): @abstractproperty def property(self): pass @@ -22,7 +22,7 @@ def property(self): AbstractProperty() def test_abstract_method(self): - class AbstractMethod(AbstractClass): + class AbstractMethod(ABC): @abstractmethod def method(self): pass @@ -213,7 +213,7 @@ def static_property(): self.assertFalse(hasattr(DeleteValue, 'static_property')) def test_abstract_classproperty(self): - class Abstract(AbstractClass): + class Abstract(ABC): @classproperty @abstractproperty def f(cls):