Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/reusable-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ jobs:
path: config.cache
key: ${{ github.job }}-${{ inputs.os }}-${{ env.IMAGE_VERSION }}-${{ inputs.config_hash }}
- name: Install Homebrew dependencies
run: brew install pkg-config [email protected] xz gdbm tcl-tk make
run: |
brew install pkg-config [email protected] xz gdbm tcl-tk@8 make
# Because alternate versions are not symlinked into place by default:
brew link tcl-tk@8
- name: Configure CPython
run: |
GDBM_CFLAGS="-I$(brew --prefix gdbm)/include" \
Expand Down
11 changes: 5 additions & 6 deletions Doc/library/ctypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2035,9 +2035,9 @@ Utility functions

.. function:: FormatError([code])

Returns a textual description of the error code *code*. If no
error code is specified, the last error code is used by calling the Windows
api function GetLastError.
Returns a textual description of the error code *code*. If no error code is
specified, the last error code is used by calling the Windows API function
:func:`GetLastError`.

.. availability:: Windows

Expand Down Expand Up @@ -2142,9 +2142,8 @@ Utility functions

.. function:: WinError(code=None, descr=None)

This function is probably the worst-named thing in ctypes. It
creates an instance of :exc:`OSError`. If *code* is not specified,
``GetLastError`` is called to determine the error code. If *descr* is not
Creates an instance of :exc:`OSError`. If *code* is not specified,
:func:`GetLastError` is called to determine the error code. If *descr* is not
specified, :func:`FormatError` is called to get a textual description of the
error.

Expand Down
15 changes: 15 additions & 0 deletions Lib/test/test_threading_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,21 @@ def test_threading_local_clear_race(self):

_testcapi.join_temporary_c_thread()

@support.cpython_only
def test_error(self):
class Loop(self._local):
attr = 1

# Trick the "if name == '__dict__':" test of __setattr__()
# to always be true
class NameCompareTrue:
def __eq__(self, other):
return True

loop = Loop()
with self.assertRaisesRegex(AttributeError, 'Loop.*read-only'):
loop.__setattr__(NameCompareTrue(), 2)


class ThreadLocalTest(unittest.TestCase, BaseLocalTest):
_local = _thread._local
Expand Down
2 changes: 1 addition & 1 deletion Modules/_threadmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1624,7 +1624,7 @@ local_setattro(localobject *self, PyObject *name, PyObject *v)
}
if (r == 1) {
PyErr_Format(PyExc_AttributeError,
"'%.100s' object attribute '%U' is read-only",
"'%.100s' object attribute %R is read-only",
Py_TYPE(self)->tp_name, name);
goto err;
}
Expand Down
Loading