Skip to content

Commit

Permalink
Catch up with main
Browse files Browse the repository at this point in the history
  • Loading branch information
brandtbucher committed Jun 16, 2023
2 parents f9a9aab + 2beab5b commit a1640c7
Show file tree
Hide file tree
Showing 15 changed files with 215 additions and 107 deletions.
14 changes: 0 additions & 14 deletions .azure-pipelines/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,6 @@ jobs:
- template: ./prebuild-checks.yml


- job: Docs_PR
displayName: Docs PR
dependsOn: Prebuild
condition: and(succeeded(), eq(dependencies.Prebuild.outputs['docs.run'], 'true'))

pool:
vmImage: ubuntu-22.04

steps:
- template: ./docs-steps.yml
parameters:
upload: true


- job: macOS_CI_Tests
displayName: macOS CI Tests
dependsOn: Prebuild
Expand Down
47 changes: 0 additions & 47 deletions .azure-pipelines/docs-steps.yml

This file was deleted.

12 changes: 0 additions & 12 deletions .azure-pipelines/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,6 @@ jobs:
- template: ./prebuild-checks.yml


- job: Docs_PR
displayName: Docs PR
dependsOn: Prebuild
condition: and(succeeded(), eq(dependencies.Prebuild.outputs['docs.run'], 'true'))

pool:
vmImage: ubuntu-22.04

steps:
- template: ./docs-steps.yml


- job: macOS_PR_Tests
displayName: macOS PR Tests
dependsOn: Prebuild
Expand Down
12 changes: 0 additions & 12 deletions .azure-pipelines/prebuild-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,6 @@ steps:
displayName: Fetch comparison tree
condition: and(succeeded(), variables['System.PullRequest.TargetBranch'])

- script: |
if ! git diff --name-only $(diffTarget) | grep -qE '(\.rst$|^Doc|^Misc)'
then
echo "No docs were updated: docs.run=false"
echo "##vso[task.setvariable variable=run;isOutput=true]false"
else
echo "Docs were updated: docs.run=true"
echo "##vso[task.setvariable variable=run;isOutput=true]true"
fi
displayName: Detect documentation changes
name: docs

- script: |
if ! git diff --name-only $(diffTarget) | grep -qvE '(\.rst$|^Doc|^Misc)'
then
Expand Down
10 changes: 5 additions & 5 deletions Doc/extending/newtypes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ representation of the instance for which it is called. Here is a simple
example::

static PyObject *
newdatatype_repr(newdatatypeobject * obj)
newdatatype_repr(newdatatypeobject *obj)
{
return PyUnicode_FromFormat("Repr-ified_newdatatype{{size:%d}}",
obj->obj_UnderlyingDatatypePtr->size);
Expand All @@ -188,7 +188,7 @@ used instead.
Here is a simple example::

static PyObject *
newdatatype_str(newdatatypeobject * obj)
newdatatype_str(newdatatypeobject *obj)
{
return PyUnicode_FromFormat("Stringified_newdatatype{{size:%d}}",
obj->obj_UnderlyingDatatypePtr->size);
Expand Down Expand Up @@ -338,7 +338,7 @@ Here is an example::

PyErr_Format(PyExc_AttributeError,
"'%.100s' object has no attribute '%.400s'",
tp->tp_name, name);
Py_TYPE(obj)->tp_name, name);
return NULL;
}

Expand Down Expand Up @@ -379,7 +379,7 @@ Here is a sample implementation, for a datatype that is considered equal if the
size of an internal pointer is equal::

static PyObject *
newdatatype_richcmp(PyObject *obj1, PyObject *obj2, int op)
newdatatype_richcmp(newdatatypeobject *obj1, newdatatypeobject *obj2, int op)
{
PyObject *result;
int c, size1, size2;
Expand Down Expand Up @@ -478,7 +478,7 @@ This function takes three arguments:
Here is a toy ``tp_call`` implementation::

static PyObject *
newdatatype_call(newdatatypeobject *self, PyObject *args, PyObject *kwds)
newdatatype_call(newdatatypeobject *obj, PyObject *args, PyObject *kwds)
{
PyObject *result;
const char *arg1;
Expand Down
4 changes: 2 additions & 2 deletions Doc/faq/general.rst
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ Python versions are numbered "A.B.C" or "A.B":

See :pep:`6` for more information about bugfix releases.

Not all releases are bugfix releases. In the run-up to a new major release, a
Not all releases are bugfix releases. In the run-up to a new minor release, a
series of development releases are made, denoted as alpha, beta, or release
candidate. Alphas are early releases in which interfaces aren't yet finalized;
it's not unexpected to see an interface change between two alpha releases.
Expand Down Expand Up @@ -297,7 +297,7 @@ How stable is Python?

Very stable. New, stable releases have been coming out roughly every 6 to 18
months since 1991, and this seems likely to continue. As of version 3.9,
Python will have a major new release every 12 months (:pep:`602`).
Python will have a minor new release every 12 months (:pep:`602`).

The developers issue "bugfix" releases of older versions, so the stability of
existing releases gradually improves. Bugfix releases, indicated by a third
Expand Down
2 changes: 1 addition & 1 deletion Doc/install/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ is supplied to suppress this behaviour. So you could simply edit
import sys
sys.path.append('/www/python/')
However, if you reinstall the same major version of Python (perhaps when
However, if you reinstall the same minor version of Python (perhaps when
upgrading from 2.2 to 2.2.2, for example) :file:`site.py` will be overwritten by
the stock version. You'd have to remember that it was modified and save a copy
before doing the installation.
Expand Down
29 changes: 20 additions & 9 deletions Doc/library/dis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1419,23 +1419,34 @@ iterations of the loop.
.. versionadded:: 3.11


.. opcode:: MAKE_FUNCTION (flags)
.. opcode:: MAKE_FUNCTION

Pushes a new function object on the stack. From bottom to top, the consumed
stack must consist of values if the argument carries a specified flag value
Pushes a new function object on the stack built from the code object at ``STACK[1]``.

.. versionchanged:: 3.10
Flag value ``0x04`` is a tuple of strings instead of dictionary

.. versionchanged:: 3.11
Qualified name at ``STACK[-1]`` was removed.

.. versionchanged:: 3.13
Extra function attributes on the stack, signaled by oparg flags, were
removed. They now use :opcode:`SET_FUNCTION_ATTRIBUTE`.


.. opcode:: SET_FUNCTION_ATTRIBUTE (flag)

Sets an attribute on a function object. Expects the function at ``STACK[-1]``
and the attribute value to set at ``STACK[-2]``; consumes both and leaves the
function at ``STACK[-1]``. The flag determines which attribute to set:

* ``0x01`` a tuple of default values for positional-only and
positional-or-keyword parameters in positional order
* ``0x02`` a dictionary of keyword-only parameters' default values
* ``0x04`` a tuple of strings containing parameters' annotations
* ``0x08`` a tuple containing cells for free variables, making a closure
* the code associated with the function (at ``STACK[-1]``)

.. versionchanged:: 3.10
Flag value ``0x04`` is a tuple of strings instead of dictionary

.. versionchanged:: 3.11
Qualified name at ``STACK[-1]`` was removed.
.. versionadded:: 3.13


.. opcode:: BUILD_SLICE (argc)
Expand Down
6 changes: 4 additions & 2 deletions Lib/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,8 @@ def visit_ClassDef(self, node):
self.fill("@")
self.traverse(deco)
self.fill("class " + node.name)
self._type_params_helper(node.type_params)
if hasattr(node, "type_params"):
self._type_params_helper(node.type_params)
with self.delimit_if("(", ")", condition = node.bases or node.keywords):
comma = False
for e in node.bases:
Expand Down Expand Up @@ -1083,7 +1084,8 @@ def _function_helper(self, node, fill_suffix):
self.traverse(deco)
def_str = fill_suffix + " " + node.name
self.fill(def_str)
self._type_params_helper(node.type_params)
if hasattr(node, "type_params"):
self._type_params_helper(node.type_params)
with self.delimit("(", ")"):
self.traverse(node.args)
if node.returns:
Expand Down
29 changes: 29 additions & 0 deletions Lib/test/test_opcache.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,35 @@ def f():
self.assertFalse(f())


class TestCallCache(unittest.TestCase):
def test_too_many_defaults_0(self):
def f():
pass

f.__defaults__ = (None,)
for _ in range(1025):
f()

def test_too_many_defaults_1(self):
def f(x):
pass

f.__defaults__ = (None, None)
for _ in range(1025):
f(None)
f()

def test_too_many_defaults_2(self):
def f(x, y):
pass

f.__defaults__ = (None, None, None)
for _ in range(1025):
f(None, None)
f(None)
f()


if __name__ == "__main__":
import unittest
unittest.main()
74 changes: 74 additions & 0 deletions Lib/test/test_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2759,6 +2759,80 @@ def x(self): ...
with self.assertRaisesRegex(TypeError, only_classes_allowed):
issubclass(1, BadPG)

def test_implicit_issubclass_between_two_protocols(self):
@runtime_checkable
class CallableMembersProto(Protocol):
def meth(self): ...

# All the below protocols should be considered "subclasses"
# of CallableMembersProto at runtime,
# even though none of them explicitly subclass CallableMembersProto

class IdenticalProto(Protocol):
def meth(self): ...

class SupersetProto(Protocol):
def meth(self): ...
def meth2(self): ...

class NonCallableMembersProto(Protocol):
meth: Callable[[], None]

class NonCallableMembersSupersetProto(Protocol):
meth: Callable[[], None]
meth2: Callable[[str, int], bool]

class MixedMembersProto1(Protocol):
meth: Callable[[], None]
def meth2(self): ...

class MixedMembersProto2(Protocol):
def meth(self): ...
meth2: Callable[[str, int], bool]

for proto in (
IdenticalProto, SupersetProto, NonCallableMembersProto,
NonCallableMembersSupersetProto, MixedMembersProto1, MixedMembersProto2
):
with self.subTest(proto=proto.__name__):
self.assertIsSubclass(proto, CallableMembersProto)

# These two shouldn't be considered subclasses of CallableMembersProto, however,
# since they don't have the `meth` protocol member

class EmptyProtocol(Protocol): ...
class UnrelatedProtocol(Protocol):
def wut(self): ...

self.assertNotIsSubclass(EmptyProtocol, CallableMembersProto)
self.assertNotIsSubclass(UnrelatedProtocol, CallableMembersProto)

# These aren't protocols at all (despite having annotations),
# so they should only be considered subclasses of CallableMembersProto
# if they *actually have an attribute* matching the `meth` member
# (just having an annotation is insufficient)

class AnnotatedButNotAProtocol:
meth: Callable[[], None]

class NotAProtocolButAnImplicitSubclass:
def meth(self): pass

class NotAProtocolButAnImplicitSubclass2:
meth: Callable[[], None]
def meth(self): pass

class NotAProtocolButAnImplicitSubclass3:
meth: Callable[[], None]
meth2: Callable[[int, str], bool]
def meth(self): pass
def meth(self, x, y): return True

self.assertNotIsSubclass(AnnotatedButNotAProtocol, CallableMembersProto)
self.assertIsSubclass(NotAProtocolButAnImplicitSubclass, CallableMembersProto)
self.assertIsSubclass(NotAProtocolButAnImplicitSubclass2, CallableMembersProto)
self.assertIsSubclass(NotAProtocolButAnImplicitSubclass3, CallableMembersProto)

def test_isinstance_checks_not_at_whim_of_gc(self):
self.addCleanup(gc.enable)
gc.disable()
Expand Down
Loading

0 comments on commit a1640c7

Please sign in to comment.