Skip to content

Commit d6740d7

Browse files
authored
Merge branch 'main' into binary_op_list_list
2 parents a018c03 + afbe137 commit d6740d7

File tree

3 files changed

+26
-15
lines changed

3 files changed

+26
-15
lines changed

Lib/dataclasses.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import re
21
import sys
3-
import copy
42
import types
53
import inspect
64
import keyword
75
import itertools
86
import annotationlib
97
import abc
108
from reprlib import recursive_repr
9+
lazy import copy
10+
lazy import re
1111

1212

1313
__all__ = ['dataclass',
@@ -217,9 +217,8 @@ def __repr__(self):
217217
_POST_INIT_NAME = '__post_init__'
218218

219219
# String regex that string annotations for ClassVar or InitVar must match.
220-
# Allows "identifier.identifier[" or "identifier[".
221-
# https://bugs.python.org/issue33453 for details.
222-
_MODULE_IDENTIFIER_RE = re.compile(r'^(?:\s*(\w+)\s*\.)?\s*(\w+)')
220+
# This regular expression is compiled on demand so that 're' module can be imported lazily
221+
_MODULE_IDENTIFIER_RE = None
223222

224223
# Atomic immutable types which don't require any recursive handling and for which deepcopy
225224
# returns the same object. We can provide a fast-path for these types in asdict and astuple.
@@ -804,10 +803,17 @@ def _is_type(annotation, cls, a_module, a_type, is_type_predicate):
804803
# a eval() penalty for every single field of every dataclass
805804
# that's defined. It was judged not worth it.
806805

807-
match = _MODULE_IDENTIFIER_RE.match(annotation)
806+
# String regex that string annotations for ClassVar or InitVar must match.
807+
# Allows "identifier.identifier[" or "identifier[".
808+
# https://github.com/python/cpython/issues/77634 for details.
809+
global _MODULE_IDENTIFIER_RE
810+
if _MODULE_IDENTIFIER_RE is None:
811+
_MODULE_IDENTIFIER_RE = re.compile(r'(?:\s*(\w+)\s*\.)?\s*(\w+)')
812+
813+
match = _MODULE_IDENTIFIER_RE.prefixmatch(annotation)
808814
if match:
809815
ns = None
810-
module_name = match.group(1)
816+
module_name = match[1]
811817
if not module_name:
812818
# No module name, assume the class's module did
813819
# "from dataclasses import InitVar".
@@ -817,7 +823,7 @@ def _is_type(annotation, cls, a_module, a_type, is_type_predicate):
817823
module = sys.modules.get(cls.__module__)
818824
if module and module.__dict__.get(module_name) is a_module:
819825
ns = sys.modules.get(a_type.__module__).__dict__
820-
if ns and is_type_predicate(ns.get(match.group(2)), a_module):
826+
if ns and is_type_predicate(ns.get(match[2]), a_module):
821827
return True
822828
return False
823829

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Improve import time of :mod:`dataclasses` module by lazy importing :mod:`re`
2+
and :mod:`copy` modules.

Modules/_bz2module.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -524,10 +524,12 @@ decompress(BZ2Decompressor *d, char *data, size_t len, Py_ssize_t max_length)
524524
if (d->eof) {
525525
FT_ATOMIC_STORE_CHAR_RELAXED(d->needs_input, 0);
526526
if (d->bzs_avail_in_real > 0) {
527-
Py_XSETREF(d->unused_data,
528-
PyBytes_FromStringAndSize(bzs->next_in, d->bzs_avail_in_real));
529-
if (d->unused_data == NULL)
527+
PyObject *unused_data = PyBytes_FromStringAndSize(
528+
bzs->next_in, d->bzs_avail_in_real);
529+
if (unused_data == NULL) {
530530
goto error;
531+
}
532+
Py_XSETREF(d->unused_data, unused_data);
531533
}
532534
}
533535
else if (d->bzs_avail_in_real == 0) {
@@ -687,12 +689,13 @@ static PyObject *
687689
BZ2Decompressor_unused_data_get(PyObject *op, void *Py_UNUSED(ignored))
688690
{
689691
BZ2Decompressor *self = _BZ2Decompressor_CAST(op);
692+
if (!FT_ATOMIC_LOAD_CHAR_RELAXED(self->eof)) {
693+
return Py_GetConstant(Py_CONSTANT_EMPTY_BYTES);
694+
}
690695
PyMutex_Lock(&self->mutex);
691-
PyObject *result = Py_XNewRef(self->unused_data);
696+
assert(self->unused_data != NULL);
697+
PyObject *result = Py_NewRef(self->unused_data);
692698
PyMutex_Unlock(&self->mutex);
693-
if (result == NULL) {
694-
PyErr_SetString(PyExc_AttributeError, "unused_data");
695-
}
696699
return result;
697700
}
698701

0 commit comments

Comments
 (0)