Skip to content

Commit

Permalink
Merge branch 'main' into fix/compiler-warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
mdickinson authored Mar 6, 2024
2 parents 55bb8fe + 95cfc08 commit caaa30a
Show file tree
Hide file tree
Showing 16 changed files with 41 additions and 104 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/run-core-traits-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12', '3.13']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', '3.13.0-alpha.3']

runs-on: ${{ matrix.os }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run-traits-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']

runs-on: ${{ matrix.os }}

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test-from-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
python-architecture: [x86, x64]
exclude:
- os: macos-latest
Expand Down Expand Up @@ -68,7 +68,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
python-architecture: [x86, x64]
exclude:
- os: macos-latest
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ inherited by any subclass derived from the class.
Dependencies
------------

Traits requires Python >= 3.6.
Traits requires Python >= 3.8.

Traits has the following optional dependencies:

Expand Down
2 changes: 1 addition & 1 deletion docs/source/traits_user_manual/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ where the Traits package has been used, it has proven valuable for enhancing
programmers' ability to understand code, during both concurrent
development and maintenance.

The Traits |version| package works with versions 3.5 and later of
The Traits |version| package works with versions 3.8 and later of
Python. It is similar in some ways to the Python property language feature.
Standard Python properties provide the similar capabilities to the Traits
package, but with more work on the part of the programmer.
Expand Down
16 changes: 7 additions & 9 deletions etstool.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
python etstool.py test-all
Currently supported runtime values are ``3.6``. Not all
Currently supported runtime values are ``3.8``. Not all
combinations of runtimes will work, but the tasks will fail with
a clear error if that is the case.
Expand Down Expand Up @@ -93,22 +93,20 @@
"enthought_sphinx_theme",
"flake8",
"flake8_ets",
"lark-parser",
"mypy",
"numpy",
"pyside6",
"Sphinx",
"sphinx_copybutton",
"traitsui",
}

# Dependencies on the Python runtime.
runtime_dependencies = {
"3.6": {"pyqt5", "lark_parser", "mypy"},
"3.8": {"pyside6"},
}
runtime_dependencies = {}

# Dependencies that need to be installed from PyPI
pypi_dependencies = {
"3.8": {"lark-parser", "mypy"}
}
pypi_dependencies = {}

# Dependencies we install from source for testing
source_dependencies = {"traitsui"}
Expand All @@ -118,7 +116,7 @@
"gnureadline",
}

supported_runtimes = ["3.6", "3.8"]
supported_runtimes = ["3.8"]
default_runtime = "3.8"

github_url_fmt = "git+http://github.com/enthought/{0}.git#egg={0}"
Expand Down
20 changes: 3 additions & 17 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,13 +276,6 @@ def get_long_description():
Operating System :: POSIX :: Linux
Programming Language :: Python
Programming Language :: Python :: 3
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Programming Language :: Python :: Implementation :: CPython
Topic :: Scientific/Engineering
Topic :: Software Development
Expand All @@ -301,11 +294,6 @@ def get_long_description():
"Documentation": "https://docs.enthought.com/traits",
"Source Code": "https://github.com/enthought/traits",
},
install_requires=[
# We need typing-extensions for SupportsIndex; once we no longer
# support Python < 3.8, we can drop this requirement.
'typing-extensions; python_version<"3.8"',
],
extras_require={
"docs": [
"enthought-sphinx-theme",
Expand All @@ -317,11 +305,9 @@ def get_long_description():
"flake8",
"flake8-ets",
"mypy",
# NumPy is not yet available for Python 3.12, but that should be
# fixed soon: https://github.com/numpy/numpy/issues/23808
"numpy; python_version < '3.12'",
"numpy",
"pyface",
"PySide6; python_version >= '3.7' and python_version < '3.12'",
"PySide6",
"setuptools",
"Sphinx>=2.1.0",
"traitsui",
Expand Down Expand Up @@ -359,6 +345,6 @@ def get_long_description():
},
license="BSD",
packages=setuptools.find_packages(include=["traits", "traits.*"]),
python_requires=">=3.6",
python_requires=">=3.8",
zip_safe=False,
)
22 changes: 6 additions & 16 deletions traits/ctraits.c
Original file line number Diff line number Diff line change
Expand Up @@ -808,18 +808,10 @@ static void
has_traits_dealloc(has_traits_object *obj)
{
PyObject_GC_UnTrack(obj);
#if PY_VERSION_HEX < 0x03080000
Py_TRASHCAN_SAFE_BEGIN(obj);
#else
Py_TRASHCAN_BEGIN(obj, has_traits_dealloc);
#endif
has_traits_clear(obj);
Py_TYPE(obj)->tp_free((PyObject *)obj);
#if PY_VERSION_HEX < 0x03080000
Py_TRASHCAN_SAFE_END(obj);
#else
Py_TRASHCAN_END
#endif
}

/*-----------------------------------------------------------------------------
Expand Down Expand Up @@ -3400,10 +3392,9 @@ validate_trait_integer(
Here float-like means:
- is an instance of float, or
- can be converted to a float via its type's __float__ method
Note: as of Python 3.8, objects having an __index__ method but
no __float__ method can also be converted to float.
- can be converted to a float via its type's __float__ method, or
- can be converted to an int (and from there to a float) via its type's
__index__ method
*/

static PyObject *
Expand Down Expand Up @@ -3470,8 +3461,7 @@ validate_trait_float(
- can be converted to a a complex number via its type's __complex__ method,
or
- can be converted to a float via its type's __float__ method, or
- (for Python >= 3.8) can be converted to an int via its type's __index__
method.
- can be converted to an int via its type's __index__ method.
In other words, these should be exactly the Python objects that are
accepted by the standard functions in the cmath module.
Expand Down Expand Up @@ -3505,8 +3495,8 @@ _ctraits_validate_complex_number(PyObject *self, PyObject *value)
/*-----------------------------------------------------------------------------
| Verifies that a Python value is convertible to a complex number.
|
| Will convert anything whose type has a __complex__, __float__ or (for
| Python >= 3.8) __index__ method to a Python complex number. Returns a Python
| Will convert anything whose type has a __complex__, __float__ or
| __index__ method to a Python complex number. Returns a Python
| object of exact type "complex". Raises TraitError with a suitable message if
| the given value isn't convertible to a complex number.
|
Expand Down
14 changes: 0 additions & 14 deletions traits/tests/test_complex.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,6 @@ def __index__(self):
return self._value


# Python versions < 3.8 don't support conversion of something with __index__
# to complex.
try:
complex(IntegerLike(3))
except TypeError:
complex_accepts_index = False
else:
complex_accepts_index = True


class FloatLike:
def __init__(self, value):
self._value = value
Expand Down Expand Up @@ -108,10 +98,6 @@ class ComplexSubclass(complex):
self.assertIs(type(a.value), complex)
self.assertEqual(a.value, complex(5.0, 12.0))

@unittest.skipUnless(
complex_accepts_index,
"complex does not support __index__ for this Python version",
)
def test_accepts_integer_like(self):
a = self.test_class()
a.value = IntegerLike(3)
Expand Down
14 changes: 6 additions & 8 deletions traits/tests/test_extended_trait_change.py
Original file line number Diff line number Diff line change
Expand Up @@ -586,10 +586,9 @@ def test_instance_list_value(self):
AssertionError,
msg="Behavior of a bug (#537) is not reproduced."):
# Handlers with arguments are unexpectedly called, but one of the
# handlers fails, leading to the rest of the handlers
# not to be called. Actual behavior depends on dictionary ordering
# (Python <3.6) or the order of handlers defined in
# InstanceValueListener (Python >= 3.6)
# handlers fails, leading to the rest of the handlers not to be
# called. Actual behavior depends on the order of handlers defined
# in InstanceValueListener.
self.assertEqual(inst.calls, {0: 1, 1: 0, 2: 0, 3: 0, 4: 0})

self.assertEqual(inst.ref.value, [0, 1, 2, 3])
Expand Down Expand Up @@ -646,10 +645,9 @@ def test_instance_dict_value(self):
AssertionError,
msg="Behavior of a bug (#537) is not reproduced."):
# Handlers with arguments are unexpectedly called, but one of the
# handlers fails, leading to the rest of the handlers
# not to be called. Actual behavior depends on dictionary ordering
# (Python <3.6) or the order of handlers defined in
# InstanceValueListener (Python >= 3.6)
# handlers fails, leading to the rest of the handlers not to be
# called. Actual behavior depends on the order of handlers defined
# in InstanceValueListener.
self.assertEqual(inst.calls, {0: 1, 1: 0, 2: 0, 3: 0, 4: 0})

self.assertEqual(inst.ref.value, {0: 0, 1: 1, 2: 2, 3: 3})
Expand Down
14 changes: 0 additions & 14 deletions traits/tests/test_float.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,6 @@ def __index__(self):
return self._value


# Python versions < 3.8 don't support conversion of something with __index__
# to float.
try:
float(IntegerLike(3))
except TypeError:
float_accepts_index = False
else:
float_accepts_index = True


class MyFloat(object):
def __init__(self, value):
self._value = value
Expand Down Expand Up @@ -111,10 +101,6 @@ def test_accepts_int(self):
self.assertIs(type(a.value_or_none), float)
self.assertEqual(a.value_or_none, 2.0)

@unittest.skipUnless(
float_accepts_index,
"float does not support __index__ for this Python version",
)
def test_accepts_integer_like(self):
a = self.test_class()
a.value = IntegerLike(3)
Expand Down
8 changes: 4 additions & 4 deletions traits/tests/test_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ class Person(HasTraits):

p = Person()

# Since we're using Python >= 3.6, we can rely on dictionaries
# being ordered, and then the default is predictable.
# Default is predictable because in all supported versions of
# Python, dictionary insertion order is preserved.
self.assertEqual(p.married, "yes")
self.assertEqual(p.married_, 1)

Expand All @@ -86,8 +86,8 @@ class Person(HasTraits):
shadow_value = p.married_
primary_value = p.married

# For Python >= 3.6, dictionary ordering and hence the default
# value are predictable.
# In all recent Python versions, dictionary ordering is deterministic
# and hence the default value is predictable.
self.assertEqual(primary_value, "yes")
self.assertEqual(shadow_value, 1)

Expand Down
4 changes: 2 additions & 2 deletions traits/tests/test_prefix_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ class Person(HasTraits):

p = Person()

# Since we're using Python >= 3.6, we can rely on dictionaries
# being ordered, and then the default is predictable.
# In all recent Python versions, dictionary ordering is deterministic
# and hence the default value is predictable.
self.assertEqual(p.married, "yes")
self.assertEqual(p.married_, 1)

Expand Down
5 changes: 1 addition & 4 deletions traits/tests/test_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,10 +291,7 @@ def test_subclasses_weakref(self):
_create_subclass()
gc.collect()

# In Python < 3.6, we can end up seeing the same subclasses but in
# a different order, so use assertCountEqual rather than assertEqual.
# Ref: enthought/traits#1282.
self.assertCountEqual(previous_subclasses, HasTraits.__subclasses__())
self.assertEqual(previous_subclasses, HasTraits.__subclasses__())

def test_leaked_property_tuple(self):
""" the property ctrait constructor shouldn't leak a tuple. """
Expand Down
7 changes: 5 additions & 2 deletions traits/trait_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,11 @@ def safe_contains(value, container):
TypeError. In these cases we make the (reasonable) assumption that the
value is _not_ contained in the container.
"""
# Do a LBYL check for Enums, to avoid the DeprecationWarning issued
# by Python 3.7. Ref: enthought/traits#853.
# Enums have an awkward history here. A containment check of an element
# against an enum.Enum subclass variously returns, raises, and/or warns
# depending on the Python version. So we do a LBYL check to bypass the
# warnings and errors.
# Ref: enthought/traits#853.
if isinstance(container, enum.EnumMeta):
if not isinstance(value, enum.Enum):
return False
Expand Down
9 changes: 1 addition & 8 deletions traits/trait_types.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

import datetime
from pathlib import PurePath as _PurePath
import sys
from typing import (
Any as _Any,
Callable as _CallableType,
Expand All @@ -20,20 +19,14 @@ from typing import (
Sequence as _Sequence,
Set as _SetType,
SupportsFloat,
SupportsIndex,
Tuple as _Tuple,
Type as _Type,
TypeVar,
Union as _Union,
)
from uuid import UUID as _UUID

# Once we no longer support Python 3.6 or Python 3.7, we can import
# SupportsIndex from typing instead of typing_extensions.
if sys.version_info < (3, 8):
from typing_extensions import SupportsIndex
else:
from typing import SupportsIndex

from .trait_type import _TraitType

SetTypes: _Any
Expand Down

0 comments on commit caaa30a

Please sign in to comment.