Skip to content

Commit

Permalink
Merge branch 'main' into pythongh-104102-optimize-glob-parent
Browse files Browse the repository at this point in the history
  • Loading branch information
barneygale committed May 2, 2023
2 parents f268157 + 47770a1 commit 581e8c5
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 16 deletions.
2 changes: 1 addition & 1 deletion Doc/library/copyreg.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Such constructors may be factory functions or class instances.

Declares that *function* should be used as a "reduction" function for objects
of type *type*. *function* must return either a string or a tuple
containing two or five elements. See the :attr:`~pickle.Pickler.dispatch_table`
containing between two and six elements. See the :attr:`~pickle.Pickler.dispatch_table`
for more details on the interface of *function*.

The *constructor_ob* parameter is a legacy feature and is now ignored, but if
Expand Down
3 changes: 1 addition & 2 deletions Lib/calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ class Day(IntEnum):
SUNDAY = 6



# Number of days per month (except for February in leap years)
mdays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

Expand Down Expand Up @@ -156,7 +155,7 @@ def weekday(year, month, day):
"""Return weekday (0-6 ~ Mon-Sun) for year, month (1-12), day (1-31)."""
if not datetime.MINYEAR <= year <= datetime.MAXYEAR:
year = 2000 + year % 400
return datetime.date(year, month, day).weekday()
return Day(datetime.date(year, month, day).weekday())


def monthrange(year, month):
Expand Down
29 changes: 16 additions & 13 deletions Lib/pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ def _is_wildcard_pattern(pat):
# be looked up directly as a file.
return "*" in pat or "?" in pat or "[" in pat

def _is_case_sensitive(flavour):
return flavour.normcase('Aa') == 'Aa'

#
# Globbing helpers
#
Expand Down Expand Up @@ -102,25 +105,24 @@ def select_from(self, parent_path):
is_dir = path_cls.is_dir
exists = path_cls.exists
scandir = path_cls._scandir
normcase = path_cls._flavour.normcase
if not is_dir(parent_path):
return iter([])
return self._select_from(parent_path, is_dir, exists, scandir, normcase)
return self._select_from(parent_path, is_dir, exists, scandir)


class _TerminatingSelector:

def _select_from(self, parent_path, is_dir, exists, scandir, normcase):
def _select_from(self, parent_path, is_dir, exists, scandir):
yield parent_path


class _ParentSelector(_Selector):
def __init__(self, name, child_parts, case_sensitive):
_Selector.__init__(self, child_parts, case_sensitive)

def _select_from(self, parent_path, is_dir, exists, scandir, normcase):
def _select_from(self, parent_path, is_dir, exists, scandir):
path = parent_path._make_child_relpath('..')
for p in self.successor._select_from(path, is_dir, exists, scandir, normcase):
for p in self.successor._select_from(path, is_dir, exists, scandir):
yield p


Expand All @@ -130,11 +132,11 @@ def __init__(self, name, child_parts, flavour):
self.name = name
_Selector.__init__(self, child_parts, flavour)

def _select_from(self, parent_path, is_dir, exists, scandir, normcase):
def _select_from(self, parent_path, is_dir, exists, scandir):
try:
path = parent_path._make_child_relpath(self.name)
if (is_dir if self.dironly else exists)(path):
for p in self.successor._select_from(path, is_dir, exists, scandir, normcase):
for p in self.successor._select_from(path, is_dir, exists, scandir):
yield p
except PermissionError:
return
Expand All @@ -143,10 +145,11 @@ def _select_from(self, parent_path, is_dir, exists, scandir, normcase):
class _WildcardSelector(_Selector):

def __init__(self, pat, child_parts, flavour):
self.match = re.compile(fnmatch.translate(flavour.normcase(pat))).fullmatch
flags = re.NOFLAG if _is_case_sensitive(flavour) else re.IGNORECASE
self.match = re.compile(fnmatch.translate(pat), flags=flags).fullmatch
_Selector.__init__(self, child_parts, flavour)

def _select_from(self, parent_path, is_dir, exists, scandir, normcase):
def _select_from(self, parent_path, is_dir, exists, scandir):
try:
# We must close the scandir() object before proceeding to
# avoid exhausting file descriptors when globbing deep trees.
Expand All @@ -165,9 +168,9 @@ def _select_from(self, parent_path, is_dir, exists, scandir, normcase):
raise
continue
name = entry.name
if self.match(normcase(name)):
if self.match(name):
path = parent_path._make_child_relpath(name)
for p in self.successor._select_from(path, is_dir, exists, scandir, normcase):
for p in self.successor._select_from(path, is_dir, exists, scandir):
yield p
except PermissionError:
return
Expand Down Expand Up @@ -199,13 +202,13 @@ def _iterate_directories(self, parent_path, is_dir, scandir):
except PermissionError:
return

def _select_from(self, parent_path, is_dir, exists, scandir, normcase):
def _select_from(self, parent_path, is_dir, exists, scandir):
try:
yielded = set()
try:
successor_select = self.successor._select_from
for starting_point in self._iterate_directories(parent_path, is_dir, scandir):
for p in successor_select(starting_point, is_dir, exists, scandir, normcase):
for p in successor_select(starting_point, is_dir, exists, scandir):
if p not in yielded:
yield p
yielded.add(p)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Update the return type of ``weekday`` to the newly added Day attribute
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Improve performance of :meth:`pathlib.Path.glob` by using
:data:`re.IGNORECASE` to implement case-insensitive matching.

0 comments on commit 581e8c5

Please sign in to comment.