diff options
author | robot-piglet <robot-piglet@yandex-team.com> | 2024-03-01 08:14:44 +0300 |
---|---|---|
committer | robot-piglet <robot-piglet@yandex-team.com> | 2024-03-01 08:23:22 +0300 |
commit | 2a3178dcfd26fc0bbd8f07409ca880f7b7f39a8b (patch) | |
tree | 317aaf3f7f88d69867860e2de5388c34e324d8f8 | |
parent | 33bd3dfbfe7a189db201a984903c52c465332299 (diff) | |
download | ydb-2a3178dcfd26fc0bbd8f07409ca880f7b7f39a8b.tar.gz |
Intermediate changes
93 files changed, 611 insertions, 189 deletions
diff --git a/contrib/python/fonttools/.dist-info/METADATA b/contrib/python/fonttools/.dist-info/METADATA index b335b936d7..a711f82b4e 100644 --- a/contrib/python/fonttools/.dist-info/METADATA +++ b/contrib/python/fonttools/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: fonttools -Version: 4.48.1 +Version: 4.49.0 Summary: Tools to manipulate font files Home-page: http://github.com/fonttools/fonttools Author: Just van Rossum @@ -375,6 +375,11 @@ Have fun! Changelog ~~~~~~~~~ +4.49.0 (released 2024-02-15) +---------------------------- + +- [otlLib] Add API for building ``MATH`` table (#3446) + 4.48.1 (released 2024-02-06) ---------------------------- @@ -723,10 +728,10 @@ Minor release to fix uploading wheels to PyPI. ---------------------------- - [varLib.instancer] Added support for L4 instancing, i.e. moving the default value of - an axis while keeping it variable. Thanks Behdad! (#2728, #2861). + an axis while keeping it variable. Thanks Behdad! (#2728, #2861). It's now also possible to restrict an axis min/max values beyond the current default value, e.g. a font wght has min=100, def=400, max=900 and you want a partial VF that - only varies between 500 and 700, you can now do that. + only varies between 500 and 700, you can now do that. You can either specify two min/max values (wght=500:700), and the new default will be set to either the minimum or maximum, depending on which one is closer to the current default (e.g. 500 in this case). Or you can specify three values (e.g. wght=500:600:700) @@ -734,7 +739,7 @@ Minor release to fix uploading wheels to PyPI. - [otlLib/featureVars] Set a few Count values so one doesn't need to compile the font to update them (#2860). - [varLib.models] Make extrapolation work for 2-master models as well where one master - is at the default location (#2843, #2846). + is at the default location (#2843, #2846). Add optional extrapolate=False to normalizeLocation() (#2847, #2849). - [varLib.cff] Fixed sub-optimal packing of CFF2 deltas by no longer rounding them to integer (#2838). diff --git a/contrib/python/fonttools/fontTools/__init__.py b/contrib/python/fonttools/fontTools/__init__.py index feb093929e..e6a745bd52 100644 --- a/contrib/python/fonttools/fontTools/__init__.py +++ b/contrib/python/fonttools/fontTools/__init__.py @@ -3,6 +3,6 @@ from fontTools.misc.loggingTools import configLogger log = logging.getLogger(__name__) -version = __version__ = "4.48.1" +version = __version__ = "4.49.0" __all__ = ["version", "log", "configLogger"] diff --git a/contrib/python/fonttools/fontTools/afmLib.py b/contrib/python/fonttools/fontTools/afmLib.py index e89646951c..0aabf7f635 100644 --- a/contrib/python/fonttools/fontTools/afmLib.py +++ b/contrib/python/fonttools/fontTools/afmLib.py @@ -45,7 +45,6 @@ Here is an example of using `afmLib` to read, modify and write an AFM file: """ - import re # every single line starts with a "word" diff --git a/contrib/python/fonttools/fontTools/cffLib/__init__.py b/contrib/python/fonttools/fontTools/cffLib/__init__.py index 644508c155..0ad41c5674 100644 --- a/contrib/python/fonttools/fontTools/cffLib/__init__.py +++ b/contrib/python/fonttools/fontTools/cffLib/__init__.py @@ -2880,7 +2880,6 @@ class PrivateDict(BaseDict): class IndexedStrings(object): - """SID -> string mapping.""" def __init__(self, file=None): diff --git a/contrib/python/fonttools/fontTools/colorLib/builder.py b/contrib/python/fonttools/fontTools/colorLib/builder.py index 442bc20e42..6e45e7a885 100644 --- a/contrib/python/fonttools/fontTools/colorLib/builder.py +++ b/contrib/python/fonttools/fontTools/colorLib/builder.py @@ -2,6 +2,7 @@ colorLib.builder: Build COLR/CPAL tables from scratch """ + import collections import copy import enum @@ -298,11 +299,15 @@ def buildPaletteLabels( labels: Iterable[_OptionalLocalizedString], nameTable: _n_a_m_e.table__n_a_m_e ) -> List[Optional[int]]: return [ - nameTable.addMultilingualName(l, mac=False) - if isinstance(l, dict) - else C_P_A_L_.table_C_P_A_L_.NO_NAME_ID - if l is None - else nameTable.addMultilingualName({"en": l}, mac=False) + ( + nameTable.addMultilingualName(l, mac=False) + if isinstance(l, dict) + else ( + C_P_A_L_.table_C_P_A_L_.NO_NAME_ID + if l is None + else nameTable.addMultilingualName({"en": l}, mac=False) + ) + ) for l in labels ] diff --git a/contrib/python/fonttools/fontTools/config/__init__.py b/contrib/python/fonttools/fontTools/config/__init__.py index c106fe51fc..41ab8f7581 100644 --- a/contrib/python/fonttools/fontTools/config/__init__.py +++ b/contrib/python/fonttools/fontTools/config/__init__.py @@ -6,6 +6,7 @@ etc. If this file gets too big, split it into smaller files per-module. An instance of the Config class can be attached to a TTFont object, so that the various modules can access their configuration options from it. """ + from textwrap import dedent from fontTools.misc.configTools import * diff --git a/contrib/python/fonttools/fontTools/designspaceLib/__init__.py b/contrib/python/fonttools/fontTools/designspaceLib/__init__.py index d6789f5f61..342f1decd5 100644 --- a/contrib/python/fonttools/fontTools/designspaceLib/__init__.py +++ b/contrib/python/fonttools/fontTools/designspaceLib/__init__.py @@ -1434,9 +1434,9 @@ class BaseDocWriter(object): ): axesElement = ET.Element("axes") if self.documentObject.elidedFallbackName is not None: - axesElement.attrib[ - "elidedfallbackname" - ] = self.documentObject.elidedFallbackName + axesElement.attrib["elidedfallbackname"] = ( + self.documentObject.elidedFallbackName + ) self.root.append(axesElement) for axisObject in self.documentObject.axes: self._addAxis(axisObject) @@ -1776,17 +1776,17 @@ class BaseDocWriter(object): if instanceObject.filename is not None: instanceElement.attrib["filename"] = instanceObject.filename if instanceObject.postScriptFontName is not None: - instanceElement.attrib[ - "postscriptfontname" - ] = instanceObject.postScriptFontName + instanceElement.attrib["postscriptfontname"] = ( + instanceObject.postScriptFontName + ) if instanceObject.styleMapFamilyName is not None: - instanceElement.attrib[ - "stylemapfamilyname" - ] = instanceObject.styleMapFamilyName + instanceElement.attrib["stylemapfamilyname"] = ( + instanceObject.styleMapFamilyName + ) if instanceObject.styleMapStyleName is not None: - instanceElement.attrib[ - "stylemapstylename" - ] = instanceObject.styleMapStyleName + instanceElement.attrib["stylemapstylename"] = ( + instanceObject.styleMapStyleName + ) if self.effectiveFormatTuple < (5, 0): # Deprecated members as of version 5.0 if instanceObject.glyphs: diff --git a/contrib/python/fonttools/fontTools/designspaceLib/statNames.py b/contrib/python/fonttools/fontTools/designspaceLib/statNames.py index a164169da6..1474e5fcf5 100644 --- a/contrib/python/fonttools/fontTools/designspaceLib/statNames.py +++ b/contrib/python/fonttools/fontTools/designspaceLib/statNames.py @@ -8,6 +8,7 @@ instance: names = getStatNames(doc, instance.getFullUserLocation(doc)) print(names.styleNames) """ + from __future__ import annotations from dataclasses import dataclass diff --git a/contrib/python/fonttools/fontTools/merge/layout.py b/contrib/python/fonttools/fontTools/merge/layout.py index 6b85cd5033..e1b504e619 100644 --- a/contrib/python/fonttools/fontTools/merge/layout.py +++ b/contrib/python/fonttools/fontTools/merge/layout.py @@ -169,20 +169,16 @@ otTables.BaseTagList.mergeMap = { "BaselineTag": sumLists, } -otTables.GDEF.mergeMap = ( - otTables.GSUB.mergeMap -) = ( - otTables.GPOS.mergeMap -) = otTables.BASE.mergeMap = otTables.JSTF.mergeMap = otTables.MATH.mergeMap = { +otTables.GDEF.mergeMap = otTables.GSUB.mergeMap = otTables.GPOS.mergeMap = ( + otTables.BASE.mergeMap +) = otTables.JSTF.mergeMap = otTables.MATH.mergeMap = { "*": mergeObjects, "Version": max, } -ttLib.getTableClass("GDEF").mergeMap = ttLib.getTableClass( - "GSUB" -).mergeMap = ttLib.getTableClass("GPOS").mergeMap = ttLib.getTableClass( - "BASE" -).mergeMap = ttLib.getTableClass( +ttLib.getTableClass("GDEF").mergeMap = ttLib.getTableClass("GSUB").mergeMap = ( + ttLib.getTableClass("GPOS").mergeMap +) = ttLib.getTableClass("BASE").mergeMap = ttLib.getTableClass( "JSTF" ).mergeMap = ttLib.getTableClass( "MATH" diff --git a/contrib/python/fonttools/fontTools/misc/classifyTools.py b/contrib/python/fonttools/fontTools/misc/classifyTools.py index 2235bbd7f8..aed7ca68c4 100644 --- a/contrib/python/fonttools/fontTools/misc/classifyTools.py +++ b/contrib/python/fonttools/fontTools/misc/classifyTools.py @@ -3,7 +3,6 @@ class Classifier(object): - """ Main Classifier object, used to classify things into similar sets. """ diff --git a/contrib/python/fonttools/fontTools/misc/cliTools.py b/contrib/python/fonttools/fontTools/misc/cliTools.py index 8322ea9ebb..8a64235bf0 100644 --- a/contrib/python/fonttools/fontTools/misc/cliTools.py +++ b/contrib/python/fonttools/fontTools/misc/cliTools.py @@ -1,4 +1,5 @@ """Collection of utilities for command-line interfaces and console scripts.""" + import os import re diff --git a/contrib/python/fonttools/fontTools/misc/configTools.py b/contrib/python/fonttools/fontTools/misc/configTools.py index 38bbada24a..7eb1854fdf 100644 --- a/contrib/python/fonttools/fontTools/misc/configTools.py +++ b/contrib/python/fonttools/fontTools/misc/configTools.py @@ -8,6 +8,7 @@ To create your own config system, you need to create an instance of ``options`` class variable set to your instance of Options. """ + from __future__ import annotations import logging diff --git a/contrib/python/fonttools/fontTools/misc/dictTools.py b/contrib/python/fonttools/fontTools/misc/dictTools.py index e3c0df7355..cd3d394c25 100644 --- a/contrib/python/fonttools/fontTools/misc/dictTools.py +++ b/contrib/python/fonttools/fontTools/misc/dictTools.py @@ -1,6 +1,5 @@ """Misc dict tools.""" - __all__ = ["hashdict"] diff --git a/contrib/python/fonttools/fontTools/misc/etree.py b/contrib/python/fonttools/fontTools/misc/etree.py index 9d4a65c360..d0967b5f52 100644 --- a/contrib/python/fonttools/fontTools/misc/etree.py +++ b/contrib/python/fonttools/fontTools/misc/etree.py @@ -11,6 +11,7 @@ or subclasses built-in ElementTree classes to add features that are only availble in lxml, like OrderedDict for attributes, pretty_print and iterwalk. """ + from fontTools.misc.textTools import tostr diff --git a/contrib/python/fonttools/fontTools/misc/filenames.py b/contrib/python/fonttools/fontTools/misc/filenames.py index d279f89cc8..ddedc5210f 100644 --- a/contrib/python/fonttools/fontTools/misc/filenames.py +++ b/contrib/python/fonttools/fontTools/misc/filenames.py @@ -17,7 +17,6 @@ by Tal Leming and is copyright (c) 2005-2016, The RoboFab Developers: - Just van Rossum """ - illegalCharacters = r"\" * + / : < > ? [ \ ] | \0".split(" ") illegalCharacters += [chr(i) for i in range(1, 32)] illegalCharacters += [chr(0x7F)] diff --git a/contrib/python/fonttools/fontTools/misc/textTools.py b/contrib/python/fonttools/fontTools/misc/textTools.py index f7ca1acc9b..f5484a83aa 100644 --- a/contrib/python/fonttools/fontTools/misc/textTools.py +++ b/contrib/python/fonttools/fontTools/misc/textTools.py @@ -1,6 +1,5 @@ """fontTools.misc.textTools.py -- miscellaneous routines.""" - import ast import string diff --git a/contrib/python/fonttools/fontTools/misc/transform.py b/contrib/python/fonttools/fontTools/misc/transform.py index f85b54b731..0f9f3a5d8b 100644 --- a/contrib/python/fonttools/fontTools/misc/transform.py +++ b/contrib/python/fonttools/fontTools/misc/transform.py @@ -76,7 +76,6 @@ def _normSinCos(v): class Transform(NamedTuple): - """2x2 transformation matrix plus offset, a.k.a. Affine transform. Transform instances are immutable: all transforming methods, eg. rotate(), return a new Transform instance. diff --git a/contrib/python/fonttools/fontTools/misc/vector.py b/contrib/python/fonttools/fontTools/misc/vector.py index 666ff15cf8..02c62e6512 100644 --- a/contrib/python/fonttools/fontTools/misc/vector.py +++ b/contrib/python/fonttools/fontTools/misc/vector.py @@ -8,7 +8,6 @@ __all__ = ["Vector"] class Vector(tuple): - """A math-like vector. Represents an n-dimensional numeric vector. ``Vector`` objects support diff --git a/contrib/python/fonttools/fontTools/otlLib/builder.py b/contrib/python/fonttools/fontTools/otlLib/builder.py index c8b14fc666..70fd87ab57 100644 --- a/contrib/python/fonttools/fontTools/otlLib/builder.py +++ b/contrib/python/fonttools/fontTools/otlLib/builder.py @@ -1,6 +1,7 @@ from collections import namedtuple, OrderedDict import os from fontTools.misc.fixedTools import fixedToFloat +from fontTools.misc.roundTools import otRound from fontTools import ttLib from fontTools.ttLib.tables import otTables as ot from fontTools.ttLib.tables.otBase import ( @@ -2906,3 +2907,294 @@ def _addName(ttFont, value, minNameID=0, windows=True, mac=True): return nameTable.addMultilingualName( names, ttFont=ttFont, windows=windows, mac=mac, minNameID=minNameID ) + + +def buildMathTable( + ttFont, + constants=None, + italicsCorrections=None, + topAccentAttachments=None, + extendedShapes=None, + mathKerns=None, + minConnectorOverlap=0, + vertGlyphVariants=None, + horizGlyphVariants=None, + vertGlyphAssembly=None, + horizGlyphAssembly=None, +): + """ + Add a 'MATH' table to 'ttFont'. + + 'constants' is a dictionary of math constants. The keys are the constant + names from the MATH table specification (with capital first letter), and the + values are the constant values as numbers. + + 'italicsCorrections' is a dictionary of italic corrections. The keys are the + glyph names, and the values are the italic corrections as numbers. + + 'topAccentAttachments' is a dictionary of top accent attachments. The keys + are the glyph names, and the values are the top accent horizontal positions + as numbers. + + 'extendedShapes' is a set of extended shape glyphs. + + 'mathKerns' is a dictionary of math kerns. The keys are the glyph names, and + the values are dictionaries. The keys of these dictionaries are the side + names ('TopRight', 'TopLeft', 'BottomRight', 'BottomLeft'), and the values + are tuples of two lists. The first list contains the correction heights as + numbers, and the second list contains the kern values as numbers. + + 'minConnectorOverlap' is the minimum connector overlap as a number. + + 'vertGlyphVariants' is a dictionary of vertical glyph variants. The keys are + the glyph names, and the values are tuples of glyph name and full advance height. + + 'horizGlyphVariants' is a dictionary of horizontal glyph variants. The keys + are the glyph names, and the values are tuples of glyph name and full + advance width. + + 'vertGlyphAssembly' is a dictionary of vertical glyph assemblies. The keys + are the glyph names, and the values are tuples of assembly parts and italics + correction. The assembly parts are tuples of glyph name, flags, start + connector length, end connector length, and full advance height. + + 'horizGlyphAssembly' is a dictionary of horizontal glyph assemblies. The + keys are the glyph names, and the values are tuples of assembly parts + and italics correction. The assembly parts are tuples of glyph name, flags, + start connector length, end connector length, and full advance width. + + Where a number is expected, an integer or a float can be used. The floats + will be rounded. + + Example:: + + constants = { + "ScriptPercentScaleDown": 70, + "ScriptScriptPercentScaleDown": 50, + "DelimitedSubFormulaMinHeight": 24, + "DisplayOperatorMinHeight": 60, + ... + } + italicsCorrections = { + "fitalic-math": 100, + "fbolditalic-math": 120, + ... + } + topAccentAttachments = { + "circumflexcomb": 500, + "acutecomb": 400, + "A": 300, + "B": 340, + ... + } + extendedShapes = {"parenleft", "parenright", ...} + mathKerns = { + "A": { + "TopRight": ([-50, -100], [10, 20, 30]), + "TopLeft": ([50, 100], [10, 20, 30]), + ... + }, + ... + } + vertGlyphVariants = { + "parenleft": [("parenleft", 700), ("parenleft.size1", 1000), ...], + "parenright": [("parenright", 700), ("parenright.size1", 1000), ...], + ... + } + vertGlyphAssembly = { + "braceleft": [ + ( + ("braceleft.bottom", 0, 0, 200, 500), + ("braceleft.extender", 1, 200, 200, 200)), + ("braceleft.middle", 0, 100, 100, 700), + ("braceleft.extender", 1, 200, 200, 200), + ("braceleft.top", 0, 200, 0, 500), + ), + 100, + ], + ... + } + """ + glyphMap = ttFont.getReverseGlyphMap() + + ttFont["MATH"] = math = ttLib.newTable("MATH") + math.table = table = ot.MATH() + table.Version = 0x00010000 + table.populateDefaults() + + table.MathConstants = _buildMathConstants(constants) + table.MathGlyphInfo = _buildMathGlyphInfo( + glyphMap, + italicsCorrections, + topAccentAttachments, + extendedShapes, + mathKerns, + ) + table.MathVariants = _buildMathVariants( + glyphMap, + minConnectorOverlap, + vertGlyphVariants, + horizGlyphVariants, + vertGlyphAssembly, + horizGlyphAssembly, + ) + + +def _buildMathConstants(constants): + if not constants: + return None + + mathConstants = ot.MathConstants() + for conv in mathConstants.getConverters(): + value = otRound(constants.get(conv.name, 0)) + if conv.tableClass: + assert issubclass(conv.tableClass, ot.MathValueRecord) + value = _mathValueRecord(value) + setattr(mathConstants, conv.name, value) + return mathConstants + + +def _buildMathGlyphInfo( + glyphMap, + italicsCorrections, + topAccentAttachments, + extendedShapes, + mathKerns, +): + if not any([extendedShapes, italicsCorrections, topAccentAttachments, mathKerns]): + return None + + info = ot.MathGlyphInfo() + info.populateDefaults() + + if italicsCorrections: + coverage = buildCoverage(italicsCorrections.keys(), glyphMap) + info.MathItalicsCorrectionInfo = ot.MathItalicsCorrectionInfo() + info.MathItalicsCorrectionInfo.Coverage = coverage + info.MathItalicsCorrectionInfo.ItalicsCorrectionCount = len(coverage.glyphs) + info.MathItalicsCorrectionInfo.ItalicsCorrection = [ + _mathValueRecord(italicsCorrections[n]) for n in coverage.glyphs + ] + + if topAccentAttachments: + coverage = buildCoverage(topAccentAttachments.keys(), glyphMap) + info.MathTopAccentAttachment = ot.MathTopAccentAttachment() + info.MathTopAccentAttachment.TopAccentCoverage = coverage + info.MathTopAccentAttachment.TopAccentAttachmentCount = len(coverage.glyphs) + info.MathTopAccentAttachment.TopAccentAttachment = [ + _mathValueRecord(topAccentAttachments[n]) for n in coverage.glyphs + ] + + if extendedShapes: + info.ExtendedShapeCoverage = buildCoverage(extendedShapes, glyphMap) + + if mathKerns: + coverage = buildCoverage(mathKerns.keys(), glyphMap) + info.MathKernInfo = ot.MathKernInfo() + info.MathKernInfo.MathKernCoverage = coverage + info.MathKernInfo.MathKernCount = len(coverage.glyphs) + info.MathKernInfo.MathKernInfoRecords = [] + for glyph in coverage.glyphs: + record = ot.MathKernInfoRecord() + for side in {"TopRight", "TopLeft", "BottomRight", "BottomLeft"}: + if side in mathKerns[glyph]: + correctionHeights, kernValues = mathKerns[glyph][side] + assert len(correctionHeights) == len(kernValues) - 1 + kern = ot.MathKern() + kern.HeightCount = len(correctionHeights) + kern.CorrectionHeight = [ + _mathValueRecord(h) for h in correctionHeights + ] + kern.KernValue = [_mathValueRecord(v) for v in kernValues] + setattr(record, f"{side}MathKern", kern) + info.MathKernInfo.MathKernInfoRecords.append(record) + + return info + + +def _buildMathVariants( + glyphMap, + minConnectorOverlap, + vertGlyphVariants, + horizGlyphVariants, + vertGlyphAssembly, + horizGlyphAssembly, +): + if not any( + [vertGlyphVariants, horizGlyphVariants, vertGlyphAssembly, horizGlyphAssembly] + ): + return None + + variants = ot.MathVariants() + variants.populateDefaults() + + variants.MinConnectorOverlap = minConnectorOverlap + + if vertGlyphVariants or vertGlyphAssembly: + variants.VertGlyphCoverage, variants.VertGlyphConstruction = ( + _buildMathGlyphConstruction( + glyphMap, + vertGlyphVariants, + vertGlyphAssembly, + ) + ) + + if horizGlyphVariants or horizGlyphAssembly: + variants.HorizGlyphCoverage, variants.HorizGlyphConstruction = ( + _buildMathGlyphConstruction( + glyphMap, + horizGlyphVariants, + horizGlyphAssembly, + ) + ) + + return variants + + +def _buildMathGlyphConstruction(glyphMap, variants, assemblies): + glyphs = set() + if variants: + glyphs.update(variants.keys()) + if assemblies: + glyphs.update(assemblies.keys()) + coverage = buildCoverage(glyphs, glyphMap) + constructions = [] + + for glyphName in coverage.glyphs: + construction = ot.MathGlyphConstruction() + construction.populateDefaults() + + if variants and glyphName in variants: + construction.VariantCount = len(variants[glyphName]) + construction.MathGlyphVariantRecord = [] + for variantName, advance in variants[glyphName]: + record = ot.MathGlyphVariantRecord() + record.VariantGlyph = variantName + record.AdvanceMeasurement = otRound(advance) + construction.MathGlyphVariantRecord.append(record) + + if assemblies and glyphName in assemblies: + parts, ic = assemblies[glyphName] + construction.GlyphAssembly = ot.GlyphAssembly() + construction.GlyphAssembly.ItalicsCorrection = _mathValueRecord(ic) + construction.GlyphAssembly.PartCount = len(parts) + construction.GlyphAssembly.PartRecords = [] + for part in parts: + part_name, flags, start, end, advance = part + record = ot.GlyphPartRecord() + record.glyph = part_name + record.PartFlags = int(flags) + record.StartConnectorLength = otRound(start) + record.EndConnectorLength = otRound(end) + record.FullAdvance = otRound(advance) + construction.GlyphAssembly.PartRecords.append(record) + + constructions.append(construction) + + return coverage, constructions + + +def _mathValueRecord(value): + value_record = ot.MathValueRecord() + value_record.Value = otRound(value) + return value_record diff --git a/contrib/python/fonttools/fontTools/pens/basePen.py b/contrib/python/fonttools/fontTools/pens/basePen.py index ac8abd40ce..5d2cf5032c 100644 --- a/contrib/python/fonttools/fontTools/pens/basePen.py +++ b/contrib/python/fonttools/fontTools/pens/basePen.py @@ -148,7 +148,6 @@ class AbstractPen: class NullPen(AbstractPen): - """A pen that does nothing.""" def moveTo(self, pt): @@ -187,7 +186,6 @@ class MissingComponentError(KeyError): class DecomposingPen(LoggingPen): - """Implements a 'addComponent' method that decomposes components (i.e. draws them onto self as simple contours). It can also be used as a mixin class (e.g. see ContourRecordingPen). @@ -229,7 +227,6 @@ class DecomposingPen(LoggingPen): class BasePen(DecomposingPen): - """Base class for drawing pens. You must override _moveTo, _lineTo and _curveToOne. You may additionally override _closePath, _endPath, addComponent, addVarComponent, and/or _qCurveToOne. You should not diff --git a/contrib/python/fonttools/fontTools/pens/boundsPen.py b/contrib/python/fonttools/fontTools/pens/boundsPen.py index d833cc89b9..c92184413e 100644 --- a/contrib/python/fonttools/fontTools/pens/boundsPen.py +++ b/contrib/python/fonttools/fontTools/pens/boundsPen.py @@ -7,7 +7,6 @@ __all__ = ["BoundsPen", "ControlBoundsPen"] class ControlBoundsPen(BasePen): - """Pen to calculate the "control bounds" of a shape. This is the bounding box of all control points, so may be larger than the actual bounding box if there are curves that don't have points @@ -67,7 +66,6 @@ class ControlBoundsPen(BasePen): class BoundsPen(ControlBoundsPen): - """Pen to calculate the bounds of a shape. It calculates the correct bounds even when the shape contains curves that don't have points on their extremes. This is somewhat slower to compute diff --git a/contrib/python/fonttools/fontTools/pens/filterPen.py b/contrib/python/fonttools/fontTools/pens/filterPen.py index 81423109ae..6c8712c261 100644 --- a/contrib/python/fonttools/fontTools/pens/filterPen.py +++ b/contrib/python/fonttools/fontTools/pens/filterPen.py @@ -9,7 +9,6 @@ class _PassThruComponentsMixin(object): class FilterPen(_PassThruComponentsMixin, AbstractPen): - """Base class for pens that apply some transformation to the coordinates they receive and pass them to another pen. diff --git a/contrib/python/fonttools/fontTools/pens/pointInsidePen.py b/contrib/python/fonttools/fontTools/pens/pointInsidePen.py index 8a579ae4c9..e1fbbbcb1d 100644 --- a/contrib/python/fonttools/fontTools/pens/pointInsidePen.py +++ b/contrib/python/fonttools/fontTools/pens/pointInsidePen.py @@ -10,7 +10,6 @@ __all__ = ["PointInsidePen"] class PointInsidePen(BasePen): - """This pen implements "point inside" testing: to test whether a given point lies inside the shape (black) or outside (white). Instances of this class can be recycled, as long as the diff --git a/contrib/python/fonttools/fontTools/pens/quartzPen.py b/contrib/python/fonttools/fontTools/pens/quartzPen.py index 6e1228d6f2..2b8a927dc4 100644 --- a/contrib/python/fonttools/fontTools/pens/quartzPen.py +++ b/contrib/python/fonttools/fontTools/pens/quartzPen.py @@ -9,7 +9,6 @@ __all__ = ["QuartzPen"] class QuartzPen(BasePen): - """A pen that creates a CGPath Parameters diff --git a/contrib/python/fonttools/fontTools/pens/recordingPen.py b/contrib/python/fonttools/fontTools/pens/recordingPen.py index e24b65265a..4f44a4d59f 100644 --- a/contrib/python/fonttools/fontTools/pens/recordingPen.py +++ b/contrib/python/fonttools/fontTools/pens/recordingPen.py @@ -1,4 +1,5 @@ """Pen recording operations that can be accessed or replayed.""" + from fontTools.pens.basePen import AbstractPen, DecomposingPen from fontTools.pens.pointPen import AbstractPointPen diff --git a/contrib/python/fonttools/fontTools/pens/reportLabPen.py b/contrib/python/fonttools/fontTools/pens/reportLabPen.py index 2cb89c8bf4..20c9065c71 100644 --- a/contrib/python/fonttools/fontTools/pens/reportLabPen.py +++ b/contrib/python/fonttools/fontTools/pens/reportLabPen.py @@ -6,7 +6,6 @@ __all__ = ["ReportLabPen"] class ReportLabPen(BasePen): - """A pen for drawing onto a ``reportlab.graphics.shapes.Path`` object.""" def __init__(self, glyphSet, path=None): diff --git a/contrib/python/fonttools/fontTools/pens/statisticsPen.py b/contrib/python/fonttools/fontTools/pens/statisticsPen.py index 403ef39f9e..699b14ca79 100644 --- a/contrib/python/fonttools/fontTools/pens/statisticsPen.py +++ b/contrib/python/fonttools/fontTools/pens/statisticsPen.py @@ -1,5 +1,6 @@ """Pen calculating area, center of mass, variance and standard-deviation, covariance and correlation, and slant, of glyph shapes.""" + from math import sqrt, degrees, atan from fontTools.pens.basePen import BasePen, OpenContourError from fontTools.pens.momentsPen import MomentsPen @@ -52,7 +53,6 @@ class StatisticsBase: class StatisticsPen(StatisticsBase, MomentsPen): - """Pen calculating area, center of mass, variance and standard-deviation, covariance and correlation, and slant, of glyph shapes. @@ -91,7 +91,6 @@ class StatisticsPen(StatisticsBase, MomentsPen): class StatisticsControlPen(StatisticsBase, BasePen): - """Pen calculating area, center of mass, variance and standard-deviation, covariance and correlation, and slant, of glyph shapes, using the control polygon only. diff --git a/contrib/python/fonttools/fontTools/pens/teePen.py b/contrib/python/fonttools/fontTools/pens/teePen.py index 2828175a7c..939f049b9f 100644 --- a/contrib/python/fonttools/fontTools/pens/teePen.py +++ b/contrib/python/fonttools/fontTools/pens/teePen.py @@ -1,4 +1,5 @@ """Pen multiplexing drawing to one or more pens.""" + from fontTools.pens.basePen import AbstractPen diff --git a/contrib/python/fonttools/fontTools/pens/transformPen.py b/contrib/python/fonttools/fontTools/pens/transformPen.py index 2e572f612e..ff98dbddb0 100644 --- a/contrib/python/fonttools/fontTools/pens/transformPen.py +++ b/contrib/python/fonttools/fontTools/pens/transformPen.py @@ -5,7 +5,6 @@ __all__ = ["TransformPen", "TransformPointPen"] class TransformPen(FilterPen): - """Pen that transforms all coordinates using a Affine transformation, and passes them to another pen. """ diff --git a/contrib/python/fonttools/fontTools/svgLib/path/arc.py b/contrib/python/fonttools/fontTools/svgLib/path/arc.py index 3e0a211e04..4b2aa5c97b 100644 --- a/contrib/python/fonttools/fontTools/svgLib/path/arc.py +++ b/contrib/python/fonttools/fontTools/svgLib/path/arc.py @@ -4,6 +4,7 @@ The code is mostly adapted from Blink's SVGPathNormalizer::DecomposeArcToCubic https://github.com/chromium/chromium/blob/93831f2/third_party/ blink/renderer/core/svg/svg_path_parser.cc#L169-L278 """ + from fontTools.misc.transform import Identity, Scale from math import atan2, ceil, cos, fabs, isfinite, pi, radians, sin, sqrt, tan diff --git a/contrib/python/fonttools/fontTools/t1Lib/__init__.py b/contrib/python/fonttools/fontTools/t1Lib/__init__.py index a64f78097c..0475881e91 100644 --- a/contrib/python/fonttools/fontTools/t1Lib/__init__.py +++ b/contrib/python/fonttools/fontTools/t1Lib/__init__.py @@ -15,6 +15,7 @@ write(path, data, kind='OTHER', dohex=False) part should be written as hexadecimal or binary, but only if kind is 'OTHER'. """ + import fontTools from fontTools.misc import eexec from fontTools.misc.macCreatorType import getMacCreatorAndType @@ -49,7 +50,6 @@ class T1Error(Exception): class T1Font(object): - """Type 1 font class. Uses a minimal interpeter that supports just about enough PS to parse diff --git a/contrib/python/fonttools/fontTools/ttLib/macUtils.py b/contrib/python/fonttools/fontTools/ttLib/macUtils.py index 468a75ad6d..0959a6fc27 100644 --- a/contrib/python/fonttools/fontTools/ttLib/macUtils.py +++ b/contrib/python/fonttools/fontTools/ttLib/macUtils.py @@ -1,4 +1,5 @@ """ttLib.macUtils.py -- Various Mac-specific stuff.""" + from io import BytesIO from fontTools.misc.macRes import ResourceReader, ResourceError @@ -35,7 +36,6 @@ def openTTFonts(path): class SFNTResourceReader(BytesIO): - """Simple read-only file wrapper for 'sfnt' resources.""" def __init__(self, path, res_name_or_index): diff --git a/contrib/python/fonttools/fontTools/ttLib/removeOverlaps.py b/contrib/python/fonttools/fontTools/ttLib/removeOverlaps.py index 624cd47b40..4795320669 100644 --- a/contrib/python/fonttools/fontTools/ttLib/removeOverlaps.py +++ b/contrib/python/fonttools/fontTools/ttLib/removeOverlaps.py @@ -202,9 +202,11 @@ def removeOverlaps( glyphNames = sorted( glyphNames, key=lambda name: ( - glyfTable[name].getCompositeMaxpValues(glyfTable).maxComponentDepth - if glyfTable[name].isComposite() - else 0, + ( + glyfTable[name].getCompositeMaxpValues(glyfTable).maxComponentDepth + if glyfTable[name].isComposite() + else 0 + ), name, ), ) diff --git a/contrib/python/fonttools/fontTools/ttLib/scaleUpem.py b/contrib/python/fonttools/fontTools/ttLib/scaleUpem.py index 3f9b22af8f..2909bfcb2c 100644 --- a/contrib/python/fonttools/fontTools/ttLib/scaleUpem.py +++ b/contrib/python/fonttools/fontTools/ttLib/scaleUpem.py @@ -3,7 +3,6 @@ AAT and Graphite tables are not supported. CFF/CFF2 fonts are de-subroutinized.""" - from fontTools.ttLib.ttVisitor import TTVisitor import fontTools.ttLib as ttLib import fontTools.ttLib.tables.otBase as otBase diff --git a/contrib/python/fonttools/fontTools/ttLib/tables/C_O_L_R_.py b/contrib/python/fonttools/fontTools/ttLib/tables/C_O_L_R_.py index 2f03ec054f..df857842cc 100644 --- a/contrib/python/fonttools/fontTools/ttLib/tables/C_O_L_R_.py +++ b/contrib/python/fonttools/fontTools/ttLib/tables/C_O_L_R_.py @@ -7,7 +7,6 @@ from . import DefaultTable class table_C_O_L_R_(DefaultTable.DefaultTable): - """This table is structured so that you can treat it like a dictionary keyed by glyph name. ``ttFont['COLR'][<glyphName>]`` will return the color layers for any glyph. diff --git a/contrib/python/fonttools/fontTools/ttLib/tables/O_S_2f_2.py b/contrib/python/fonttools/fontTools/ttLib/tables/O_S_2f_2.py index edff91f58d..0c739bcc44 100644 --- a/contrib/python/fonttools/fontTools/ttLib/tables/O_S_2f_2.py +++ b/contrib/python/fonttools/fontTools/ttLib/tables/O_S_2f_2.py @@ -113,7 +113,6 @@ OS2_format_5_addition = bigendian + OS2_format_5_addition class table_O_S_2f_2(DefaultTable.DefaultTable): - """the OS/2 table""" dependencies = ["head"] diff --git a/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__0.py b/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__0.py index f15fc67bce..77905822a8 100644 --- a/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__0.py +++ b/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__0.py @@ -5,6 +5,7 @@ TSI0 is the index table containing the lengths and offsets for the glyph programs and 'extra' programs ('fpgm', 'prep', and 'cvt') that are contained in the TSI1 table. """ + from . import DefaultTable import struct diff --git a/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__1.py b/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__1.py index 55aca33991..a9d04a09b0 100644 --- a/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__1.py +++ b/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__1.py @@ -4,6 +4,7 @@ tool to store its hinting source data. TSI1 contains the text of the glyph programs in the form of low-level assembly code, as well as the 'extra' programs 'fpgm', 'ppgm' (i.e. 'prep'), and 'cvt'. """ + from . import DefaultTable from fontTools.misc.loggingTools import LogMixin from fontTools.misc.textTools import strjoin, tobytes, tostr diff --git a/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__2.py b/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__2.py index 4278be1556..163ef45226 100644 --- a/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__2.py +++ b/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__2.py @@ -5,6 +5,7 @@ TSI2 is the index table containing the lengths and offsets for the glyph programs that are contained in the TSI3 table. It uses the same format as the TSI0 table. """ + from fontTools import ttLib superclass = ttLib.getTableClass("TSI0") diff --git a/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__3.py b/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__3.py index 785ca23152..604a7f0beb 100644 --- a/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__3.py +++ b/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__3.py @@ -3,6 +3,7 @@ tool to store its hinting source data. TSI3 contains the text of the glyph programs in the form of 'VTTTalk' code. """ + from fontTools import ttLib superclass = ttLib.getTableClass("TSI1") diff --git a/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__5.py b/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__5.py index 5edc86a9cb..d86798695c 100644 --- a/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__5.py +++ b/contrib/python/fonttools/fontTools/ttLib/tables/T_S_I__5.py @@ -3,6 +3,7 @@ tool to store its hinting source data. TSI5 contains the VTT character groups. """ + from fontTools.misc.textTools import safeEval from . import DefaultTable import sys diff --git a/contrib/python/fonttools/fontTools/ttLib/tables/TupleVariation.py b/contrib/python/fonttools/fontTools/ttLib/tables/TupleVariation.py index 30d009906d..027ac15342 100644 --- a/contrib/python/fonttools/fontTools/ttLib/tables/TupleVariation.py +++ b/contrib/python/fonttools/fontTools/ttLib/tables/TupleVariation.py @@ -517,22 +517,22 @@ class TupleVariation(object): return # no change coordWidth = self.getCoordWidth() self.coordinates = [ - None - if d is None - else d * scalar - if coordWidth == 1 - else (d[0] * scalar, d[1] * scalar) + ( + None + if d is None + else d * scalar if coordWidth == 1 else (d[0] * scalar, d[1] * scalar) + ) for d in self.coordinates ] def roundDeltas(self): coordWidth = self.getCoordWidth() self.coordinates = [ - None - if d is None - else otRound(d) - if coordWidth == 1 - else (otRound(d[0]), otRound(d[1])) + ( + None + if d is None + else otRound(d) if coordWidth == 1 else (otRound(d[0]), otRound(d[1])) + ) for d in self.coordinates ] diff --git a/contrib/python/fonttools/fontTools/ttLib/tables/V_O_R_G_.py b/contrib/python/fonttools/fontTools/ttLib/tables/V_O_R_G_.py index 4508c137d6..b08737b224 100644 --- a/contrib/python/fonttools/fontTools/ttLib/tables/V_O_R_G_.py +++ b/contrib/python/fonttools/fontTools/ttLib/tables/V_O_R_G_.py @@ -4,7 +4,6 @@ import struct class table_V_O_R_G_(DefaultTable.DefaultTable): - """This table is structured so that you can treat it like a dictionary keyed by glyph name. ``ttFont['VORG'][<glyphName>]`` will return the vertical origin for any glyph. diff --git a/contrib/python/fonttools/fontTools/ttLib/tables/_k_e_r_n.py b/contrib/python/fonttools/fontTools/ttLib/tables/_k_e_r_n.py index 8f55a311cd..270b3b7e44 100644 --- a/contrib/python/fonttools/fontTools/ttLib/tables/_k_e_r_n.py +++ b/contrib/python/fonttools/fontTools/ttLib/tables/_k_e_r_n.py @@ -147,9 +147,9 @@ class KernTable_format_0(object): except IndexError: # Slower, but will not throw an IndexError on an invalid # glyph id. - kernTable[ - (ttFont.getGlyphName(left), ttFont.getGlyphName(right)) - ] = value + kernTable[(ttFont.getGlyphName(left), ttFont.getGlyphName(right))] = ( + value + ) if len(data) > 6 * nPairs + 4: # Ignore up to 4 bytes excess log.warning( "excess data in 'kern' subtable: %d bytes", len(data) - 6 * nPairs diff --git a/contrib/python/fonttools/fontTools/ttLib/tables/otBase.py b/contrib/python/fonttools/fontTools/ttLib/tables/otBase.py index d565603b1f..53abd13b48 100644 --- a/contrib/python/fonttools/fontTools/ttLib/tables/otBase.py +++ b/contrib/python/fonttools/fontTools/ttLib/tables/otBase.py @@ -79,7 +79,6 @@ class RepackerState(IntEnum): class BaseTTXConverter(DefaultTable): - """Generic base class for TTX table converters. It functions as an adapter between the TTX (ttLib actually) table model and the model we use for OpenType tables, which is necessarily subtly different. @@ -260,7 +259,6 @@ assert array.array("i").itemsize == 4, "Oops, file a bug against fonttools." class OTTableReader(object): - """Helper class to retrieve data from an OpenType table.""" __slots__ = ("data", "offset", "pos", "localState", "tableTag") @@ -392,7 +390,6 @@ class OffsetToWriter(object): class OTTableWriter(object): - """Helper class to gather and assemble data for OpenType tables.""" def __init__(self, localState=None, tableTag=None): @@ -882,7 +879,6 @@ def packUInt24(value): class BaseTable(object): - """Generic base class for all OpenType (sub)tables.""" def __getattr__(self, attr): @@ -1210,7 +1206,6 @@ class BaseTable(object): class FormatSwitchingBaseTable(BaseTable): - """Minor specialization of BaseTable, for tables that have multiple formats, eg. CoverageFormat1 vs. CoverageFormat2.""" @@ -1335,7 +1330,6 @@ valueRecordFormatDict = _buildDict() class ValueRecordFactory(object): - """Given a format code, this object convert ValueRecords.""" def __init__(self, valueFormat): diff --git a/contrib/python/fonttools/fontTools/ttLib/tables/otConverters.py b/contrib/python/fonttools/fontTools/ttLib/tables/otConverters.py index 390f1660e8..afe4e538f4 100644 --- a/contrib/python/fonttools/fontTools/ttLib/tables/otConverters.py +++ b/contrib/python/fonttools/fontTools/ttLib/tables/otConverters.py @@ -146,7 +146,6 @@ class _LazyList(UserList): class BaseConverter(object): - """Base class for converter objects. Apart from the constructor, this is an abstract class.""" diff --git a/contrib/python/fonttools/fontTools/ttLib/tables/otTraverse.py b/contrib/python/fonttools/fontTools/ttLib/tables/otTraverse.py index bf22dcfdb5..ac94218723 100644 --- a/contrib/python/fonttools/fontTools/ttLib/tables/otTraverse.py +++ b/contrib/python/fonttools/fontTools/ttLib/tables/otTraverse.py @@ -1,4 +1,5 @@ """Methods for traversing trees of otData-driven OpenType tables.""" + from collections import deque from typing import Callable, Deque, Iterable, List, Optional, Tuple from .otBase import BaseTable diff --git a/contrib/python/fonttools/fontTools/ttLib/tables/ttProgram.py b/contrib/python/fonttools/fontTools/ttLib/tables/ttProgram.py index 84aa63f363..32a4ec8b20 100644 --- a/contrib/python/fonttools/fontTools/ttLib/tables/ttProgram.py +++ b/contrib/python/fonttools/fontTools/ttLib/tables/ttProgram.py @@ -1,4 +1,5 @@ """ttLib.tables.ttProgram.py -- Assembler/disassembler for TrueType bytecode programs.""" + from __future__ import annotations from fontTools.misc.textTools import num2binary, binary2num, readHex, strjoin diff --git a/contrib/python/fonttools/fontTools/ttLib/ttCollection.py b/contrib/python/fonttools/fontTools/ttLib/ttCollection.py index 70ed4b7a0d..f01bc42be3 100644 --- a/contrib/python/fonttools/fontTools/ttLib/ttCollection.py +++ b/contrib/python/fonttools/fontTools/ttLib/ttCollection.py @@ -8,7 +8,6 @@ log = logging.getLogger(__name__) class TTCollection(object): - """Object representing a TrueType Collection / OpenType Collection. The main API is self.fonts being a list of TTFont instances. diff --git a/contrib/python/fonttools/fontTools/ttLib/ttFont.py b/contrib/python/fonttools/fontTools/ttLib/ttFont.py index c8c74fecfe..ad62a187de 100644 --- a/contrib/python/fonttools/fontTools/ttLib/ttFont.py +++ b/contrib/python/fonttools/fontTools/ttLib/ttFont.py @@ -15,7 +15,6 @@ log = logging.getLogger(__name__) class TTFont(object): - """Represents a TrueType font. The object manages file input and output, and offers a convenient way of @@ -843,7 +842,6 @@ class TTFont(object): class GlyphOrder(object): - """A pseudo table. The glyph order isn't in the font as a separate table, but it's nice to present it as such in the TTX format. """ diff --git a/contrib/python/fonttools/fontTools/ttLib/ttGlyphSet.py b/contrib/python/fonttools/fontTools/ttLib/ttGlyphSet.py index 5d188d6a10..b4beb3e766 100644 --- a/contrib/python/fonttools/fontTools/ttLib/ttGlyphSet.py +++ b/contrib/python/fonttools/fontTools/ttLib/ttGlyphSet.py @@ -17,7 +17,6 @@ from fontTools.pens.recordingPen import ( class _TTGlyphSet(Mapping): - """Generic dict-like GlyphSet class that pulls metrics from hmtx and glyph shape from TrueType or CFF. """ @@ -125,7 +124,6 @@ class _TTGlyphSetCFF(_TTGlyphSet): class _TTGlyph(ABC): - """Glyph object that supports the Pen protocol, meaning that it has .draw() and .drawPoints() methods that take a pen object as their only argument. Additionally there are 'width' and 'lsb' attributes, read from diff --git a/contrib/python/fonttools/fontTools/ttx.py b/contrib/python/fonttools/fontTools/ttx.py index d8c2a3a758..e7a068748b 100644 --- a/contrib/python/fonttools/fontTools/ttx.py +++ b/contrib/python/fonttools/fontTools/ttx.py @@ -103,7 +103,6 @@ Compile options extension is available at https://pypi.python.org/pypi/zopfli """ - from fontTools.ttLib import TTFont, TTLibError from fontTools.misc.macCreatorType import getMacCreatorAndType from fontTools.unicode import setUnicodeData diff --git a/contrib/python/fonttools/fontTools/ufoLib/__init__.py b/contrib/python/fonttools/fontTools/ufoLib/__init__.py index 1a456a206f..c2d2b0b266 100644 --- a/contrib/python/fonttools/fontTools/ufoLib/__init__.py +++ b/contrib/python/fonttools/fontTools/ufoLib/__init__.py @@ -197,7 +197,6 @@ class _UFOBaseIO: class UFOReader(_UFOBaseIO): - """ Read the various components of the .ufo. @@ -881,7 +880,6 @@ class UFOReader(_UFOBaseIO): class UFOWriter(UFOReader): - """ Write the various components of the .ufo. diff --git a/contrib/python/fonttools/fontTools/ufoLib/converters.py b/contrib/python/fonttools/fontTools/ufoLib/converters.py index daccf78272..88a26c616a 100644 --- a/contrib/python/fonttools/fontTools/ufoLib/converters.py +++ b/contrib/python/fonttools/fontTools/ufoLib/converters.py @@ -2,7 +2,6 @@ Conversion functions. """ - # adapted from the UFO spec diff --git a/contrib/python/fonttools/fontTools/ufoLib/etree.py b/contrib/python/fonttools/fontTools/ufoLib/etree.py index 5054f8169a..77e3c16e2b 100644 --- a/contrib/python/fonttools/fontTools/ufoLib/etree.py +++ b/contrib/python/fonttools/fontTools/ufoLib/etree.py @@ -2,4 +2,5 @@ for the old ufoLib.etree module, which was moved to fontTools.misc.etree. Please use the latter instead. """ + from fontTools.misc.etree import * diff --git a/contrib/python/fonttools/fontTools/ufoLib/glifLib.py b/contrib/python/fonttools/fontTools/ufoLib/glifLib.py index 6dee9db302..62e87db0df 100644 --- a/contrib/python/fonttools/fontTools/ufoLib/glifLib.py +++ b/contrib/python/fonttools/fontTools/ufoLib/glifLib.py @@ -91,7 +91,6 @@ GLIFFormatVersion.__str__ = _VersionTupleEnumMixin.__str__ class Glyph: - """ Minimal glyph object. It has no glyph attributes until either the draw() or the drawPoints() method has been called. @@ -123,7 +122,6 @@ class Glyph: class GlyphSet(_UFOBaseIO): - """ GlyphSet manages a set of .glif files inside one directory. @@ -1228,9 +1226,9 @@ def _readGlyphFromTreeFormat2( unicodes = [] guidelines = [] anchors = [] - haveSeenAdvance = ( - haveSeenImage - ) = haveSeenOutline = haveSeenLib = haveSeenNote = False + haveSeenAdvance = haveSeenImage = haveSeenOutline = haveSeenLib = haveSeenNote = ( + False + ) identifiers = set() for element in tree: if element.tag == "outline": @@ -1883,7 +1881,6 @@ _transformationInfo = [ class GLIFPointPen(AbstractPointPen): - """ Helper class using the PointPen protocol to write the <outline> part of .glif files. diff --git a/contrib/python/fonttools/fontTools/ufoLib/plistlib.py b/contrib/python/fonttools/fontTools/ufoLib/plistlib.py index 1f52f20a2b..38bb266b21 100644 --- a/contrib/python/fonttools/fontTools/ufoLib/plistlib.py +++ b/contrib/python/fonttools/fontTools/ufoLib/plistlib.py @@ -2,6 +2,7 @@ for the old ufoLib.plistlib module, which was moved to fontTools.misc.plistlib. Please use the latter instead. """ + from fontTools.misc.plistlib import dump, dumps, load, loads from fontTools.misc.textTools import tobytes diff --git a/contrib/python/fonttools/fontTools/ufoLib/pointPen.py b/contrib/python/fonttools/fontTools/ufoLib/pointPen.py index 3433fdbc96..baef9a583e 100644 --- a/contrib/python/fonttools/fontTools/ufoLib/pointPen.py +++ b/contrib/python/fonttools/fontTools/ufoLib/pointPen.py @@ -2,4 +2,5 @@ for the old ufoLib.pointPen module, which was moved to fontTools.pens.pointPen. Please use the latter instead. """ + from fontTools.pens.pointPen import * diff --git a/contrib/python/fonttools/fontTools/ufoLib/utils.py b/contrib/python/fonttools/fontTools/ufoLib/utils.py index 85878b47a1..45ec1c564b 100644 --- a/contrib/python/fonttools/fontTools/ufoLib/utils.py +++ b/contrib/python/fonttools/fontTools/ufoLib/utils.py @@ -1,6 +1,7 @@ """The module contains miscellaneous helpers. It's not considered part of the public ufoLib API. """ + import warnings import functools diff --git a/contrib/python/fonttools/fontTools/unicodedata/__init__.py b/contrib/python/fonttools/fontTools/unicodedata/__init__.py index 808c9c722e..06eb4619a9 100644 --- a/contrib/python/fonttools/fontTools/unicodedata/__init__.py +++ b/contrib/python/fonttools/fontTools/unicodedata/__init__.py @@ -201,15 +201,13 @@ T = TypeVar("T") @overload -def script_horizontal_direction(script_code: str, default: T) -> HorizDirection | T: - ... +def script_horizontal_direction(script_code: str, default: T) -> HorizDirection | T: ... @overload def script_horizontal_direction( script_code: str, default: type[KeyError] = KeyError -) -> HorizDirection: - ... +) -> HorizDirection: ... def script_horizontal_direction( diff --git a/contrib/python/fonttools/fontTools/varLib/__init__.py b/contrib/python/fonttools/fontTools/varLib/__init__.py index b9af6dacbf..1e0f2ec2f4 100644 --- a/contrib/python/fonttools/fontTools/varLib/__init__.py +++ b/contrib/python/fonttools/fontTools/varLib/__init__.py @@ -18,6 +18,7 @@ Then you can make a variable-font this way: API *will* change in near future. """ + from typing import List from fontTools.misc.vector import Vector from fontTools.misc.roundTools import noRound, otRound @@ -569,9 +570,11 @@ def _get_advance_metrics( sparse_advance = 0xFFFF for glyph in glyphOrder: vhAdvances = [ - metrics[glyph][0] - if glyph in metrics and metrics[glyph][0] != sparse_advance - else None + ( + metrics[glyph][0] + if glyph in metrics and metrics[glyph][0] != sparse_advance + else None + ) for metrics in advMetricses ] vhAdvanceDeltasAndSupports[glyph] = masterModel.getDeltasAndSupports( diff --git a/contrib/python/fonttools/fontTools/varLib/featureVars.py b/contrib/python/fonttools/fontTools/varLib/featureVars.py index 828b843594..2e957f5585 100644 --- a/contrib/python/fonttools/fontTools/varLib/featureVars.py +++ b/contrib/python/fonttools/fontTools/varLib/featureVars.py @@ -3,6 +3,7 @@ https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#featurevariat NOTE: The API is experimental and subject to change. """ + from fontTools.misc.dictTools import hashdict from fontTools.misc.intTools import bit_count from fontTools.ttLib import newTable diff --git a/contrib/python/fonttools/fontTools/varLib/instancer/__init__.py b/contrib/python/fonttools/fontTools/varLib/instancer/__init__.py index df55f0414d..89427dc534 100644 --- a/contrib/python/fonttools/fontTools/varLib/instancer/__init__.py +++ b/contrib/python/fonttools/fontTools/varLib/instancer/__init__.py @@ -82,6 +82,7 @@ are supported, but support for CFF2 variable fonts will be added soon. The discussion and implementation of these features are tracked at https://github.com/fonttools/fonttools/issues/1537 """ + from fontTools.misc.fixedTools import ( floatToFixedToFloat, strToFixedToFloat, @@ -643,9 +644,11 @@ def instantiateGvar(varfont, axisLimits, optimize=True): glyphnames = sorted( glyf.glyphOrder, key=lambda name: ( - glyf[name].getCompositeMaxpValues(glyf).maxComponentDepth - if glyf[name].isComposite() or glyf[name].isVarComposite() - else 0, + ( + glyf[name].getCompositeMaxpValues(glyf).maxComponentDepth + if glyf[name].isComposite() or glyf[name].isVarComposite() + else 0 + ), name, ), ) diff --git a/contrib/python/fonttools/fontTools/varLib/interpolate_layout.py b/contrib/python/fonttools/fontTools/varLib/interpolate_layout.py index aa3f49c6ed..798b29590d 100644 --- a/contrib/python/fonttools/fontTools/varLib/interpolate_layout.py +++ b/contrib/python/fonttools/fontTools/varLib/interpolate_layout.py @@ -1,6 +1,7 @@ """ Interpolate OpenType Layout tables (GDEF / GPOS / GSUB). """ + from fontTools.ttLib import TTFont from fontTools.varLib import models, VarLibError, load_designspace, load_masters from fontTools.varLib.merger import InstancerMerger diff --git a/contrib/python/fonttools/fontTools/varLib/merger.py b/contrib/python/fonttools/fontTools/varLib/merger.py index 96029166a7..61122f4c67 100644 --- a/contrib/python/fonttools/fontTools/varLib/merger.py +++ b/contrib/python/fonttools/fontTools/varLib/merger.py @@ -1,6 +1,7 @@ """ Merge OpenType Layout tables (GDEF / GPOS / GSUB). """ + import os import copy import enum diff --git a/contrib/python/fonttools/fontTools/varLib/mutator.py b/contrib/python/fonttools/fontTools/varLib/mutator.py index d1d123ab69..c7c37dabca 100644 --- a/contrib/python/fonttools/fontTools/varLib/mutator.py +++ b/contrib/python/fonttools/fontTools/varLib/mutator.py @@ -3,6 +3,7 @@ Instantiate a variation font. Run, eg: $ fonttools varLib.mutator ./NotoSansArabic-VF.ttf wght=140 wdth=85 """ + from fontTools.misc.fixedTools import floatToFixedToFloat, floatToFixed from fontTools.misc.roundTools import otRound from fontTools.pens.boundsPen import BoundsPen @@ -198,9 +199,11 @@ def instantiateVariableFont(varfont, location, inplace=False, overlap=True): glyphnames = sorted( gvar.variations.keys(), key=lambda name: ( - glyf[name].getCompositeMaxpValues(glyf).maxComponentDepth - if glyf[name].isComposite() or glyf[name].isVarComposite() - else 0, + ( + glyf[name].getCompositeMaxpValues(glyf).maxComponentDepth + if glyf[name].isComposite() or glyf[name].isVarComposite() + else 0 + ), name, ), ) @@ -304,9 +307,9 @@ def instantiateVariableFont(varfont, location, inplace=False, overlap=True): if applies: assert record.FeatureTableSubstitution.Version == 0x00010000 for rec in record.FeatureTableSubstitution.SubstitutionRecord: - table.FeatureList.FeatureRecord[ - rec.FeatureIndex - ].Feature = rec.Feature + table.FeatureList.FeatureRecord[rec.FeatureIndex].Feature = ( + rec.Feature + ) break del table.FeatureVariations diff --git a/contrib/python/fonttools/ya.make b/contrib/python/fonttools/ya.make index 35b91fddb1..e5986f9d03 100644 --- a/contrib/python/fonttools/ya.make +++ b/contrib/python/fonttools/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(4.48.1) +VERSION(4.49.0) LICENSE(MIT) diff --git a/contrib/python/google-auth/py3/.dist-info/METADATA b/contrib/python/google-auth/py3/.dist-info/METADATA index 48bac82c9d..c8e96994cf 100644 --- a/contrib/python/google-auth/py3/.dist-info/METADATA +++ b/contrib/python/google-auth/py3/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: google-auth -Version: 2.27.0 +Version: 2.28.0 Summary: Google Authentication Library Home-page: https://github.com/googleapis/google-auth-library-python Author: Google Cloud Platform diff --git a/contrib/python/google-auth/py3/google/auth/compute_engine/_metadata.py b/contrib/python/google-auth/py3/google/auth/compute_engine/_metadata.py index 1c884c3c43..108cbfe932 100644 --- a/contrib/python/google-auth/py3/google/auth/compute_engine/_metadata.py +++ b/contrib/python/google-auth/py3/google/auth/compute_engine/_metadata.py @@ -222,7 +222,7 @@ def get( content = _helpers.from_bytes(response.data) if response.status == http_client.NOT_FOUND and return_none_for_not_found_error: - _LOGGER.info( + _LOGGER.debug( "Compute Engine Metadata server call to %s returned 404, reason: %s", path, content, diff --git a/contrib/python/google-auth/py3/google/auth/compute_engine/credentials.py b/contrib/python/google-auth/py3/google/auth/compute_engine/credentials.py index 7541c1d8cf..008b991bb9 100644 --- a/contrib/python/google-auth/py3/google/auth/compute_engine/credentials.py +++ b/contrib/python/google-auth/py3/google/auth/compute_engine/credentials.py @@ -28,7 +28,6 @@ from google.auth import iam from google.auth import jwt from google.auth import metrics from google.auth.compute_engine import _metadata -from google.auth.transport import requests as google_auth_requests from google.oauth2 import _client @@ -84,7 +83,6 @@ class Credentials( self._scopes = scopes self._default_scopes = default_scopes self._universe_domain_cached = False - self._universe_domain_request = google_auth_requests.Request() if universe_domain: self._universe_domain = universe_domain self._universe_domain_cached = True @@ -150,8 +148,11 @@ class Credentials( def universe_domain(self): if self._universe_domain_cached: return self._universe_domain + + from google.auth.transport import requests as google_auth_requests + self._universe_domain = _metadata.get_universe_domain( - self._universe_domain_request + google_auth_requests.Request() ) self._universe_domain_cached = True return self._universe_domain diff --git a/contrib/python/google-auth/py3/google/auth/credentials.py b/contrib/python/google-auth/py3/google/auth/credentials.py index a4fa1829c7..27abd443dc 100644 --- a/contrib/python/google-auth/py3/google/auth/credentials.py +++ b/contrib/python/google-auth/py3/google/auth/credentials.py @@ -24,6 +24,8 @@ from google.auth import exceptions from google.auth import metrics from google.auth._refresh_worker import RefreshThreadManager +DEFAULT_UNIVERSE_DOMAIN = "googleapis.com" + class Credentials(metaclass=abc.ABCMeta): """Base class for all credentials. @@ -57,7 +59,7 @@ class Credentials(metaclass=abc.ABCMeta): """Optional[dict]: Cache of a trust boundary response which has a list of allowed regions and an encoded string representation of credentials trust boundary.""" - self._universe_domain = "googleapis.com" + self._universe_domain = DEFAULT_UNIVERSE_DOMAIN """Optional[str]: The universe domain value, default is googleapis.com """ diff --git a/contrib/python/google-auth/py3/google/auth/downscoped.py b/contrib/python/google-auth/py3/google/auth/downscoped.py index b4d9d386e5..ea75be90fe 100644 --- a/contrib/python/google-auth/py3/google/auth/downscoped.py +++ b/contrib/python/google-auth/py3/google/auth/downscoped.py @@ -63,7 +63,7 @@ _STS_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:token-exchange" # The token exchange requested_token_type. This is always an access_token. _STS_REQUESTED_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:access_token" # The STS token URL used to exchanged a short lived access token for a downscoped one. -_STS_TOKEN_URL = "https://sts.googleapis.com/v1/token" +_STS_TOKEN_URL_PATTERN = "https://sts.{}/v1/token" # The subject token type to use when exchanging a short lived access token for a # downscoped token. _STS_SUBJECT_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:access_token" @@ -437,7 +437,11 @@ class Credentials(credentials.CredentialsWithQuotaProject): """ def __init__( - self, source_credentials, credential_access_boundary, quota_project_id=None + self, + source_credentials, + credential_access_boundary, + quota_project_id=None, + universe_domain=credentials.DEFAULT_UNIVERSE_DOMAIN, ): """Instantiates a downscoped credentials object using the provided source credentials and credential access boundary rules. @@ -456,6 +460,7 @@ class Credentials(credentials.CredentialsWithQuotaProject): the upper bound of the permissions that are available on that resource and an optional condition to further restrict permissions. quota_project_id (Optional[str]): The optional quota project ID. + universe_domain (Optional[str]): The universe domain value, default is googleapis.com Raises: google.auth.exceptions.RefreshError: If the source credentials return an error on token refresh. @@ -467,7 +472,10 @@ class Credentials(credentials.CredentialsWithQuotaProject): self._source_credentials = source_credentials self._credential_access_boundary = credential_access_boundary self._quota_project_id = quota_project_id - self._sts_client = sts.Client(_STS_TOKEN_URL) + self._universe_domain = universe_domain or credentials.DEFAULT_UNIVERSE_DOMAIN + self._sts_client = sts.Client( + _STS_TOKEN_URL_PATTERN.format(self.universe_domain) + ) @_helpers.copy_docstring(credentials.Credentials) def refresh(self, request): diff --git a/contrib/python/google-auth/py3/google/auth/external_account.py b/contrib/python/google-auth/py3/google/auth/external_account.py index c314ea799e..0420883f86 100644 --- a/contrib/python/google-auth/py3/google/auth/external_account.py +++ b/contrib/python/google-auth/py3/google/auth/external_account.py @@ -51,8 +51,6 @@ _STS_REQUESTED_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:access_token" # Cloud resource manager URL used to retrieve project information. _CLOUD_RESOURCE_MANAGER = "https://cloudresourcemanager.googleapis.com/v1/projects/" -_DEFAULT_UNIVERSE_DOMAIN = "googleapis.com" - class Credentials( credentials.Scoped, @@ -83,7 +81,7 @@ class Credentials( scopes=None, default_scopes=None, workforce_pool_user_project=None, - universe_domain=_DEFAULT_UNIVERSE_DOMAIN, + universe_domain=credentials.DEFAULT_UNIVERSE_DOMAIN, trust_boundary=None, ): """Instantiates an external account credentials object. @@ -131,7 +129,7 @@ class Credentials( self._scopes = scopes self._default_scopes = default_scopes self._workforce_pool_user_project = workforce_pool_user_project - self._universe_domain = universe_domain or _DEFAULT_UNIVERSE_DOMAIN + self._universe_domain = universe_domain or credentials.DEFAULT_UNIVERSE_DOMAIN self._trust_boundary = { "locations": [], "encoded_locations": "0x0", @@ -513,7 +511,9 @@ class Credentials( credential_source=info.get("credential_source"), quota_project_id=info.get("quota_project_id"), workforce_pool_user_project=info.get("workforce_pool_user_project"), - universe_domain=info.get("universe_domain", _DEFAULT_UNIVERSE_DOMAIN), + universe_domain=info.get( + "universe_domain", credentials.DEFAULT_UNIVERSE_DOMAIN + ), **kwargs ) diff --git a/contrib/python/google-auth/py3/google/auth/external_account_authorized_user.py b/contrib/python/google-auth/py3/google/auth/external_account_authorized_user.py index 526588f7e8..f73387172c 100644 --- a/contrib/python/google-auth/py3/google/auth/external_account_authorized_user.py +++ b/contrib/python/google-auth/py3/google/auth/external_account_authorized_user.py @@ -43,7 +43,6 @@ from google.auth import exceptions from google.oauth2 import sts from google.oauth2 import utils -_DEFAULT_UNIVERSE_DOMAIN = "googleapis.com" _EXTERNAL_ACCOUNT_AUTHORIZED_USER_JSON_TYPE = "external_account_authorized_user" @@ -76,7 +75,7 @@ class Credentials( revoke_url=None, scopes=None, quota_project_id=None, - universe_domain=_DEFAULT_UNIVERSE_DOMAIN, + universe_domain=credentials.DEFAULT_UNIVERSE_DOMAIN, ): """Instantiates a external account authorized user credentials object. @@ -120,7 +119,7 @@ class Credentials( self._revoke_url = revoke_url self._quota_project_id = quota_project_id self._scopes = scopes - self._universe_domain = universe_domain or _DEFAULT_UNIVERSE_DOMAIN + self._universe_domain = universe_domain or credentials.DEFAULT_UNIVERSE_DOMAIN if not self.valid and not self.can_refresh: raise exceptions.InvalidOperation( @@ -342,7 +341,9 @@ class Credentials( revoke_url=info.get("revoke_url"), quota_project_id=info.get("quota_project_id"), scopes=info.get("scopes"), - universe_domain=info.get("universe_domain", _DEFAULT_UNIVERSE_DOMAIN), + universe_domain=info.get( + "universe_domain", credentials.DEFAULT_UNIVERSE_DOMAIN + ), **kwargs ) diff --git a/contrib/python/google-auth/py3/google/auth/version.py b/contrib/python/google-auth/py3/google/auth/version.py index e1fa722c81..9672a6c412 100644 --- a/contrib/python/google-auth/py3/google/auth/version.py +++ b/contrib/python/google-auth/py3/google/auth/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.27.0" +__version__ = "2.28.0" diff --git a/contrib/python/google-auth/py3/google/oauth2/credentials.py b/contrib/python/google-auth/py3/google/oauth2/credentials.py index c239beed13..5ca00d4c5a 100644 --- a/contrib/python/google-auth/py3/google/oauth2/credentials.py +++ b/contrib/python/google-auth/py3/google/oauth2/credentials.py @@ -49,7 +49,6 @@ _LOGGER = logging.getLogger(__name__) # The Google OAuth 2.0 token endpoint. Used for authorized user credentials. _GOOGLE_OAUTH2_TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token" -_DEFAULT_UNIVERSE_DOMAIN = "googleapis.com" class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaProject): @@ -86,7 +85,7 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr enable_reauth_refresh=False, granted_scopes=None, trust_boundary=None, - universe_domain=_DEFAULT_UNIVERSE_DOMAIN, + universe_domain=credentials.DEFAULT_UNIVERSE_DOMAIN, account=None, ): """ @@ -150,7 +149,7 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr self.refresh_handler = refresh_handler self._enable_reauth_refresh = enable_reauth_refresh self._trust_boundary = trust_boundary - self._universe_domain = universe_domain or _DEFAULT_UNIVERSE_DOMAIN + self._universe_domain = universe_domain or credentials.DEFAULT_UNIVERSE_DOMAIN self._account = account or "" def __getstate__(self): @@ -187,7 +186,9 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr self._rapt_token = d.get("_rapt_token") self._enable_reauth_refresh = d.get("_enable_reauth_refresh") self._trust_boundary = d.get("_trust_boundary") - self._universe_domain = d.get("_universe_domain") or _DEFAULT_UNIVERSE_DOMAIN + self._universe_domain = ( + d.get("_universe_domain") or credentials.DEFAULT_UNIVERSE_DOMAIN + ) # The refresh_handler setter should be used to repopulate this. self._refresh_handler = None self._refresh_worker = None @@ -373,7 +374,7 @@ class Credentials(credentials.ReadOnlyScoped, credentials.CredentialsWithQuotaPr @_helpers.copy_docstring(credentials.Credentials) def refresh(self, request): - if self._universe_domain != _DEFAULT_UNIVERSE_DOMAIN: + if self._universe_domain != credentials.DEFAULT_UNIVERSE_DOMAIN: raise exceptions.RefreshError( "User credential refresh is only supported in the default " "googleapis.com universe domain, but the current universe " diff --git a/contrib/python/google-auth/py3/google/oauth2/service_account.py b/contrib/python/google-auth/py3/google/oauth2/service_account.py index 4502c6f68c..04fd7797ad 100644 --- a/contrib/python/google-auth/py3/google/oauth2/service_account.py +++ b/contrib/python/google-auth/py3/google/oauth2/service_account.py @@ -82,7 +82,6 @@ from google.auth import metrics from google.oauth2 import _client _DEFAULT_TOKEN_LIFETIME_SECS = 3600 # 1 hour in seconds -_DEFAULT_UNIVERSE_DOMAIN = "googleapis.com" _GOOGLE_OAUTH2_TOKEN_ENDPOINT = "https://oauth2.googleapis.com/token" @@ -139,7 +138,7 @@ class Credentials( quota_project_id=None, additional_claims=None, always_use_jwt_access=False, - universe_domain=_DEFAULT_UNIVERSE_DOMAIN, + universe_domain=credentials.DEFAULT_UNIVERSE_DOMAIN, trust_boundary=None, ): """ @@ -182,9 +181,9 @@ class Credentials( self._quota_project_id = quota_project_id self._token_uri = token_uri self._always_use_jwt_access = always_use_jwt_access - self._universe_domain = universe_domain or _DEFAULT_UNIVERSE_DOMAIN + self._universe_domain = universe_domain or credentials.DEFAULT_UNIVERSE_DOMAIN - if universe_domain != _DEFAULT_UNIVERSE_DOMAIN: + if universe_domain != credentials.DEFAULT_UNIVERSE_DOMAIN: self._always_use_jwt_access = True self._jwt_credentials = None @@ -216,7 +215,9 @@ class Credentials( service_account_email=info["client_email"], token_uri=info["token_uri"], project_id=info.get("project_id"), - universe_domain=info.get("universe_domain", _DEFAULT_UNIVERSE_DOMAIN), + universe_domain=info.get( + "universe_domain", credentials.DEFAULT_UNIVERSE_DOMAIN + ), trust_boundary=info.get("trust_boundary"), **kwargs ) @@ -316,7 +317,7 @@ class Credentials( """ cred = self._make_copy() if ( - cred._universe_domain != _DEFAULT_UNIVERSE_DOMAIN + cred._universe_domain != credentials.DEFAULT_UNIVERSE_DOMAIN and not always_use_jwt_access ): raise exceptions.InvalidValue( @@ -329,7 +330,7 @@ class Credentials( def with_universe_domain(self, universe_domain): cred = self._make_copy() cred._universe_domain = universe_domain - if universe_domain != _DEFAULT_UNIVERSE_DOMAIN: + if universe_domain != credentials.DEFAULT_UNIVERSE_DOMAIN: cred._always_use_jwt_access = True return cred @@ -427,7 +428,10 @@ class Credentials( # created, try to create one with scopes self._create_self_signed_jwt(None) - if self._universe_domain != _DEFAULT_UNIVERSE_DOMAIN and self._subject: + if ( + self._universe_domain != credentials.DEFAULT_UNIVERSE_DOMAIN + and self._subject + ): raise exceptions.RefreshError( "domain wide delegation is not supported for non-default universe domain" ) @@ -556,7 +560,7 @@ class IDTokenCredentials( target_audience, additional_claims=None, quota_project_id=None, - universe_domain=_DEFAULT_UNIVERSE_DOMAIN, + universe_domain=credentials.DEFAULT_UNIVERSE_DOMAIN, ): """ Args: @@ -588,11 +592,11 @@ class IDTokenCredentials( self._use_iam_endpoint = False if not universe_domain: - self._universe_domain = _DEFAULT_UNIVERSE_DOMAIN + self._universe_domain = credentials.DEFAULT_UNIVERSE_DOMAIN else: self._universe_domain = universe_domain - if universe_domain != _DEFAULT_UNIVERSE_DOMAIN: + if universe_domain != credentials.DEFAULT_UNIVERSE_DOMAIN: self._use_iam_endpoint = True if additional_claims is not None: @@ -708,7 +712,10 @@ class IDTokenCredentials( default and use_iam_endpoint is False. """ cred = self._make_copy() - if cred._universe_domain != _DEFAULT_UNIVERSE_DOMAIN and not use_iam_endpoint: + if ( + cred._universe_domain != credentials.DEFAULT_UNIVERSE_DOMAIN + and not use_iam_endpoint + ): raise exceptions.InvalidValue( "use_iam_endpoint should be True for non-default universe domain" ) diff --git a/contrib/python/google-auth/py3/tests/compute_engine/test__metadata.py b/contrib/python/google-auth/py3/tests/compute_engine/test__metadata.py index 5e037a940b..35e3c089f9 100644 --- a/contrib/python/google-auth/py3/tests/compute_engine/test__metadata.py +++ b/contrib/python/google-auth/py3/tests/compute_engine/test__metadata.py @@ -400,6 +400,19 @@ def test_get_universe_domain_success(): assert universe_domain == "fake_universe_domain" +def test_get_universe_domain_success_empty_response(): + request = make_request("", headers={"content-type": "text/plain"}) + + universe_domain = _metadata.get_universe_domain(request) + + request.assert_called_once_with( + method="GET", + url=_metadata._METADATA_ROOT + "universe/universe_domain", + headers=_metadata._METADATA_HEADERS, + ) + assert universe_domain == "googleapis.com" + + def test_get_universe_domain_not_found(): # Test that if the universe domain endpoint returns 404 error, we should # use googleapis.com as the universe domain diff --git a/contrib/python/google-auth/py3/tests/compute_engine/test_credentials.py b/contrib/python/google-auth/py3/tests/compute_engine/test_credentials.py index f04bb1304a..9cca317924 100644 --- a/contrib/python/google-auth/py3/tests/compute_engine/test_credentials.py +++ b/contrib/python/google-auth/py3/tests/compute_engine/test_credentials.py @@ -257,16 +257,12 @@ class TestCredentials(object): assert self.credentials.universe_domain == "fake_universe_domain" assert self.credentials._universe_domain == "fake_universe_domain" assert self.credentials._universe_domain_cached - get_universe_domain.assert_called_once_with( - self.credentials._universe_domain_request - ) + get_universe_domain.assert_called_once() # calling the universe_domain property the second time should use the # cached value instead of calling get_universe_domain assert self.credentials.universe_domain == "fake_universe_domain" - get_universe_domain.assert_called_once_with( - self.credentials._universe_domain_request - ) + get_universe_domain.assert_called_once() @mock.patch("google.auth.compute_engine._metadata.get_universe_domain") def test_user_provided_universe_domain(self, get_universe_domain): diff --git a/contrib/python/google-auth/py3/tests/oauth2/test_service_account.py b/contrib/python/google-auth/py3/tests/oauth2/test_service_account.py index 8dd5f219be..ce0c72fa0a 100644 --- a/contrib/python/google-auth/py3/tests/oauth2/test_service_account.py +++ b/contrib/python/google-auth/py3/tests/oauth2/test_service_account.py @@ -24,6 +24,7 @@ from google.auth import crypt from google.auth import exceptions from google.auth import jwt from google.auth import transport +from google.auth.credentials import DEFAULT_UNIVERSE_DOMAIN from google.oauth2 import service_account @@ -59,7 +60,7 @@ class TestCredentials(object): TOKEN_URI = "https://example.com/oauth2/token" @classmethod - def make_credentials(cls, universe_domain=service_account._DEFAULT_UNIVERSE_DOMAIN): + def make_credentials(cls, universe_domain=DEFAULT_UNIVERSE_DOMAIN): return service_account.Credentials( SIGNER, cls.SERVICE_ACCOUNT_EMAIL, @@ -71,7 +72,7 @@ class TestCredentials(object): credentials = service_account.Credentials( SIGNER, self.SERVICE_ACCOUNT_EMAIL, self.TOKEN_URI, universe_domain=None ) - assert credentials.universe_domain == service_account._DEFAULT_UNIVERSE_DOMAIN + assert credentials.universe_domain == DEFAULT_UNIVERSE_DOMAIN def test_from_service_account_info(self): credentials = service_account.Credentials.from_service_account_info( @@ -81,7 +82,7 @@ class TestCredentials(object): assert credentials._signer.key_id == SERVICE_ACCOUNT_INFO["private_key_id"] assert credentials.service_account_email == SERVICE_ACCOUNT_INFO["client_email"] assert credentials._token_uri == SERVICE_ACCOUNT_INFO["token_uri"] - assert credentials._universe_domain == service_account._DEFAULT_UNIVERSE_DOMAIN + assert credentials._universe_domain == DEFAULT_UNIVERSE_DOMAIN assert not credentials._always_use_jwt_access def test_from_service_account_info_non_gdu(self): @@ -596,7 +597,7 @@ class TestIDTokenCredentials(object): TARGET_AUDIENCE = "https://example.com" @classmethod - def make_credentials(cls, universe_domain=service_account._DEFAULT_UNIVERSE_DOMAIN): + def make_credentials(cls, universe_domain=DEFAULT_UNIVERSE_DOMAIN): return service_account.IDTokenCredentials( SIGNER, cls.SERVICE_ACCOUNT_EMAIL, @@ -613,7 +614,7 @@ class TestIDTokenCredentials(object): self.TARGET_AUDIENCE, universe_domain=None, ) - assert credentials._universe_domain == service_account._DEFAULT_UNIVERSE_DOMAIN + assert credentials._universe_domain == DEFAULT_UNIVERSE_DOMAIN def test_from_service_account_info(self): credentials = service_account.IDTokenCredentials.from_service_account_info( diff --git a/contrib/python/google-auth/py3/tests/test_aws.py b/contrib/python/google-auth/py3/tests/test_aws.py index db2e984100..3f358d52b0 100644 --- a/contrib/python/google-auth/py3/tests/test_aws.py +++ b/contrib/python/google-auth/py3/tests/test_aws.py @@ -26,7 +26,7 @@ from google.auth import aws from google.auth import environment_vars from google.auth import exceptions from google.auth import transport - +from google.auth.credentials import DEFAULT_UNIVERSE_DOMAIN IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = ( "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/imp" @@ -75,7 +75,6 @@ REQUEST_PARAMS = '{"KeySchema":[{"KeyType":"HASH","AttributeName":"Id"}],"TableN # Each tuple contains the following entries: # region, time, credentials, original_request, signed_request -DEFAULT_UNIVERSE_DOMAIN = "googleapis.com" VALID_TOKEN_URLS = [ "https://sts.googleapis.com", "https://us-east-1.sts.googleapis.com", diff --git a/contrib/python/google-auth/py3/tests/test_downscoped.py b/contrib/python/google-auth/py3/tests/test_downscoped.py index 8cc2a30d16..fe6e291c75 100644 --- a/contrib/python/google-auth/py3/tests/test_downscoped.py +++ b/contrib/python/google-auth/py3/tests/test_downscoped.py @@ -25,6 +25,7 @@ from google.auth import credentials from google.auth import downscoped from google.auth import exceptions from google.auth import transport +from google.auth.credentials import DEFAULT_UNIVERSE_DOMAIN from google.auth.credentials import TokenState @@ -447,7 +448,11 @@ class TestCredentialAccessBoundary(object): class TestCredentials(object): @staticmethod - def make_credentials(source_credentials=SourceCredentials(), quota_project_id=None): + def make_credentials( + source_credentials=SourceCredentials(), + quota_project_id=None, + universe_domain=None, + ): availability_condition = make_availability_condition( EXPRESSION, TITLE, DESCRIPTION ) @@ -458,7 +463,10 @@ class TestCredentials(object): credential_access_boundary = make_credential_access_boundary(rules) return downscoped.Credentials( - source_credentials, credential_access_boundary, quota_project_id + source_credentials, + credential_access_boundary, + quota_project_id, + universe_domain, ) @staticmethod @@ -473,10 +481,12 @@ class TestCredentials(object): return request @staticmethod - def assert_request_kwargs(request_kwargs, headers, request_data): + def assert_request_kwargs( + request_kwargs, headers, request_data, token_endpoint=TOKEN_EXCHANGE_ENDPOINT + ): """Asserts the request was called with the expected parameters. """ - assert request_kwargs["url"] == TOKEN_EXCHANGE_ENDPOINT + assert request_kwargs["url"] == token_endpoint assert request_kwargs["method"] == "POST" assert request_kwargs["headers"] == headers assert request_kwargs["body"] is not None @@ -496,6 +506,33 @@ class TestCredentials(object): assert not credentials.expired # No quota project ID set. assert not credentials.quota_project_id + assert credentials.universe_domain == DEFAULT_UNIVERSE_DOMAIN + + def test_default_state_with_explicit_none_value(self): + credentials = self.make_credentials(universe_domain=None) + + # No token acquired yet. + assert not credentials.token + assert not credentials.valid + # Expiration hasn't been set yet. + assert not credentials.expiry + assert not credentials.expired + # No quota project ID set. + assert not credentials.quota_project_id + assert credentials.universe_domain == DEFAULT_UNIVERSE_DOMAIN + + def test_create_with_customized_universe_domain(self): + test_universe_domain = "foo.com" + credentials = self.make_credentials(universe_domain=test_universe_domain) + # No token acquired yet. + assert not credentials.token + assert not credentials.valid + # Expiration hasn't been set yet. + assert not credentials.expiry + assert not credentials.expired + # No quota project ID set. + assert not credentials.quota_project_id + assert credentials.universe_domain == test_universe_domain def test_with_quota_project(self): credentials = self.make_credentials() @@ -507,6 +544,49 @@ class TestCredentials(object): assert quota_project_creds.quota_project_id == "project-foo" @mock.patch("google.auth._helpers.utcnow", return_value=datetime.datetime.min) + def test_refresh_on_custom_universe(self, unused_utcnow): + test_universe_domain = "foo.com" + response = SUCCESS_RESPONSE.copy() + # Test custom expiration to confirm expiry is set correctly. + response["expires_in"] = 2800 + expected_expiry = datetime.datetime.min + datetime.timedelta( + seconds=response["expires_in"] + ) + headers = {"Content-Type": "application/x-www-form-urlencoded"} + request_data = { + "grant_type": GRANT_TYPE, + "subject_token": "ACCESS_TOKEN_1", + "subject_token_type": SUBJECT_TOKEN_TYPE, + "requested_token_type": REQUESTED_TOKEN_TYPE, + "options": urllib.parse.quote(json.dumps(CREDENTIAL_ACCESS_BOUNDARY_JSON)), + } + request = self.make_mock_request(status=http_client.OK, data=response) + source_credentials = SourceCredentials() + credentials = self.make_credentials( + source_credentials=source_credentials, universe_domain=test_universe_domain + ) + token_exchange_endpoint = downscoped._STS_TOKEN_URL_PATTERN.format( + test_universe_domain + ) + + # Spy on calls to source credentials refresh to confirm the expected request + # instance is used. + with mock.patch.object( + source_credentials, "refresh", wraps=source_credentials.refresh + ) as wrapped_souce_cred_refresh: + credentials.refresh(request) + + self.assert_request_kwargs( + request.call_args[1], headers, request_data, token_exchange_endpoint + ) + assert credentials.valid + assert credentials.expiry == expected_expiry + assert not credentials.expired + assert credentials.token == response["access_token"] + # Confirm source credentials called with the same request instance. + wrapped_souce_cred_refresh.assert_called_with(request) + + @mock.patch("google.auth._helpers.utcnow", return_value=datetime.datetime.min) def test_refresh(self, unused_utcnow): response = SUCCESS_RESPONSE.copy() # Test custom expiration to confirm expiry is set correctly. diff --git a/contrib/python/google-auth/py3/tests/test_external_account.py b/contrib/python/google-auth/py3/tests/test_external_account.py index 7f33b1dfa2..03a5014ce5 100644 --- a/contrib/python/google-auth/py3/tests/test_external_account.py +++ b/contrib/python/google-auth/py3/tests/test_external_account.py @@ -24,9 +24,9 @@ from google.auth import _helpers from google.auth import exceptions from google.auth import external_account from google.auth import transport +from google.auth.credentials import DEFAULT_UNIVERSE_DOMAIN from google.auth.credentials import TokenState - IMPERSONATE_ACCESS_TOKEN_REQUEST_METRICS_HEADER_VALUE = ( "gl-python/3.7 auth/1.1 auth-request-type/at cred-type/imp" ) @@ -150,7 +150,7 @@ class TestCredentials(object): default_scopes=None, service_account_impersonation_url=None, service_account_impersonation_options={}, - universe_domain=external_account._DEFAULT_UNIVERSE_DOMAIN, + universe_domain=DEFAULT_UNIVERSE_DOMAIN, ): return CredentialsImpl( audience=cls.AUDIENCE, @@ -386,7 +386,7 @@ class TestCredentials(object): quota_project_id=self.QUOTA_PROJECT_ID, scopes=["email"], default_scopes=["default2"], - universe_domain=external_account._DEFAULT_UNIVERSE_DOMAIN, + universe_domain=DEFAULT_UNIVERSE_DOMAIN, ) def test_with_token_uri(self): @@ -474,7 +474,7 @@ class TestCredentials(object): quota_project_id="project-foo", scopes=self.SCOPES, default_scopes=["default1"], - universe_domain=external_account._DEFAULT_UNIVERSE_DOMAIN, + universe_domain=DEFAULT_UNIVERSE_DOMAIN, ) def test_with_invalid_impersonation_target_principal(self): @@ -504,7 +504,7 @@ class TestCredentials(object): assert credentials.universe_domain == "dummy_universe.com" credentials = self.make_credentials() - assert credentials.universe_domain == external_account._DEFAULT_UNIVERSE_DOMAIN + assert credentials.universe_domain == DEFAULT_UNIVERSE_DOMAIN def test_with_universe_domain(self): credentials = self.make_credentials() @@ -523,7 +523,7 @@ class TestCredentials(object): "token_url": self.TOKEN_URL, "credential_source": self.CREDENTIAL_SOURCE.copy(), "workforce_pool_user_project": self.WORKFORCE_POOL_USER_PROJECT, - "universe_domain": external_account._DEFAULT_UNIVERSE_DOMAIN, + "universe_domain": DEFAULT_UNIVERSE_DOMAIN, } def test_info_with_full_options(self): @@ -548,7 +548,7 @@ class TestCredentials(object): "quota_project_id": self.QUOTA_PROJECT_ID, "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, - "universe_domain": external_account._DEFAULT_UNIVERSE_DOMAIN, + "universe_domain": DEFAULT_UNIVERSE_DOMAIN, } def test_service_account_email_without_impersonation(self): diff --git a/contrib/python/google-auth/py3/tests/test_external_account_authorized_user.py b/contrib/python/google-auth/py3/tests/test_external_account_authorized_user.py index 7213a23486..743ee9c848 100644 --- a/contrib/python/google-auth/py3/tests/test_external_account_authorized_user.py +++ b/contrib/python/google-auth/py3/tests/test_external_account_authorized_user.py @@ -22,6 +22,7 @@ import pytest # type: ignore from google.auth import exceptions from google.auth import external_account_authorized_user from google.auth import transport +from google.auth.credentials import DEFAULT_UNIVERSE_DOMAIN TOKEN_URL = "https://sts.googleapis.com/v1/token" TOKEN_INFO_URL = "https://sts.googleapis.com/v1/introspect" @@ -45,7 +46,6 @@ BASIC_AUTH_ENCODING = "dXNlcm5hbWU6cGFzc3dvcmQ=" SCOPES = ["email", "profile"] NOW = datetime.datetime(1990, 8, 27, 6, 54, 30) FAKE_UNIVERSE_DOMAIN = "fake-universe-domain" -DEFAULT_UNIVERSE_DOMAIN = external_account_authorized_user._DEFAULT_UNIVERSE_DOMAIN class TestCredentials(object): diff --git a/contrib/python/google-auth/py3/tests/test_identity_pool.py b/contrib/python/google-auth/py3/tests/test_identity_pool.py index 2d10a5d268..96be1d61c2 100644 --- a/contrib/python/google-auth/py3/tests/test_identity_pool.py +++ b/contrib/python/google-auth/py3/tests/test_identity_pool.py @@ -26,7 +26,7 @@ from google.auth import exceptions from google.auth import identity_pool from google.auth import metrics from google.auth import transport - +from google.auth.credentials import DEFAULT_UNIVERSE_DOMAIN CLIENT_ID = "username" CLIENT_SECRET = "password" @@ -68,8 +68,6 @@ WORKFORCE_AUDIENCE = ( WORKFORCE_SUBJECT_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:id_token" WORKFORCE_POOL_USER_PROJECT = "WORKFORCE_POOL_USER_PROJECT_NUMBER" -DEFAULT_UNIVERSE_DOMAIN = "googleapis.com" - VALID_TOKEN_URLS = [ "https://sts.googleapis.com", "https://us-east-1.sts.googleapis.com", diff --git a/contrib/python/google-auth/py3/tests/test_pluggable.py b/contrib/python/google-auth/py3/tests/test_pluggable.py index 783bbcaec0..24cd0e2ec9 100644 --- a/contrib/python/google-auth/py3/tests/test_pluggable.py +++ b/contrib/python/google-auth/py3/tests/test_pluggable.py @@ -21,6 +21,7 @@ import pytest # type: ignore from google.auth import exceptions from google.auth import pluggable +from google.auth.credentials import DEFAULT_UNIVERSE_DOMAIN from .test__default import WORKFORCE_AUDIENCE CLIENT_ID = "username" @@ -45,7 +46,6 @@ TOKEN_URL = "https://sts.googleapis.com/v1/token" TOKEN_INFO_URL = "https://sts.googleapis.com/v1/introspect" SUBJECT_TOKEN_TYPE = "urn:ietf:params:oauth:token-type:jwt" AUDIENCE = "//iam.googleapis.com/projects/123456/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID" -DEFAULT_UNIVERSE_DOMAIN = "googleapis.com" VALID_TOKEN_URLS = [ "https://sts.googleapis.com", diff --git a/contrib/python/google-auth/py3/ya.make b/contrib/python/google-auth/py3/ya.make index 5ece69bc98..7863862fdc 100644 --- a/contrib/python/google-auth/py3/ya.make +++ b/contrib/python/google-auth/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(2.27.0) +VERSION(2.28.0) LICENSE(Apache-2.0) diff --git a/contrib/python/hypothesis/py3/.dist-info/METADATA b/contrib/python/hypothesis/py3/.dist-info/METADATA index c2000db5a1..9780b83140 100644 --- a/contrib/python/hypothesis/py3/.dist-info/METADATA +++ b/contrib/python/hypothesis/py3/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: hypothesis -Version: 6.98.5 +Version: 6.98.6 Summary: A library for property-based testing Home-page: https://hypothesis.works Author: David R. MacIver and Zac Hatfield-Dodds diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py index 1f56d2ccf3..cea40823be 100644 --- a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py +++ b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py @@ -1589,7 +1589,9 @@ class ConjectureData: if forced is not None: assert allow_nan or not math.isnan(forced) - assert math.isnan(forced) or min_value <= forced <= max_value + assert math.isnan(forced) or ( + sign_aware_lte(min_value, forced) and sign_aware_lte(forced, max_value) + ) kwargs: FloatKWargs = { "min_value": min_value, diff --git a/contrib/python/hypothesis/py3/hypothesis/stateful.py b/contrib/python/hypothesis/py3/hypothesis/stateful.py index 14275d940e..2ae5815161 100644 --- a/contrib/python/hypothesis/py3/hypothesis/stateful.py +++ b/contrib/python/hypothesis/py3/hypothesis/stateful.py @@ -233,11 +233,12 @@ class StateMachineMeta(type): class RuleBasedStateMachine(metaclass=StateMachineMeta): """A RuleBasedStateMachine gives you a structured way to define state machines. - The idea is that a state machine carries a bunch of types of data - divided into Bundles, and has a set of rules which may read data - from bundles (or just from normal strategies) and push data onto - bundles. At any given point a random applicable rule will be - executed. + The idea is that a state machine carries the system under test and some supporting + data. This data can be stored in instance variables or + divided into Bundles. The state machine has a set of rules which may read data + from bundles (or just from normal strategies), push data onto + bundles, change the state of the machine, or verify properties. + At any given point a random applicable rule will be executed. """ _rules_per_class: ClassVar[Dict[type, List[classmethod]]] = {} @@ -459,6 +460,27 @@ class BundleReferenceStrategy(SearchStrategy): class Bundle(SearchStrategy[Ex]): + """A collection of values for use in stateful testing. + + Bundles are a kind of strategy where values can be added by rules, + and (like any strategy) used as inputs to future rules. + + The ``name`` argument they are passed is the they are referred to + internally by the state machine; no two bundles may have + the same name. It is idiomatic to use the attribute + being assigned to as the name of the Bundle:: + + class MyStateMachine(RuleBasedStateMachine): + keys = Bundle("keys") + + Bundles can contain the same value more than once; this becomes + relevant when using :func:`~hypothesis.stateful.consumes` to remove + values again. + + If the ``consume`` argument is set to True, then all values that are + drawn from this bundle will be consumed (as above) when requested. + """ + def __init__(self, name: str, *, consume: bool = False) -> None: self.name = name self.__reference_strategy = BundleReferenceStrategy(name, consume=consume) @@ -638,7 +660,7 @@ def rule( ``targets`` will define where the end result of this function should go. If both are empty then the end result will be discarded. - ``target`` must be a Bundle, or if the result should go to multiple + ``target`` must be a Bundle, or if the result should be replicated to multiple bundles you can pass a tuple of them as the ``targets`` argument. It is invalid to use both arguments for a single rule. If the result should go to exactly one of several bundles, define a separate rule for diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/core.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/core.py index 97dd2bf9b3..1efe75caec 100644 --- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/core.py +++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/core.py @@ -2104,6 +2104,10 @@ def runner(*, default: Any = not_set) -> SearchStrategy[Any]: The exact meaning depends on the entry point, but it will usually be the associated 'self' value for it. + If you are using this in a rule for stateful testing, this strategy + will return the instance of the :class:`~hypothesis.stateful.RuleBasedStateMachine` + that the rule is running for. + If there is no current test runner and a default is provided, return that default. If no default is provided, raises InvalidArgument. diff --git a/contrib/python/hypothesis/py3/hypothesis/version.py b/contrib/python/hypothesis/py3/hypothesis/version.py index 65284f2d57..43ec273cc1 100644 --- a/contrib/python/hypothesis/py3/hypothesis/version.py +++ b/contrib/python/hypothesis/py3/hypothesis/version.py @@ -8,5 +8,5 @@ # v. 2.0. If a copy of the MPL was not distributed with this file, You can # obtain one at https://mozilla.org/MPL/2.0/. -__version_info__ = (6, 98, 5) +__version_info__ = (6, 98, 6) __version__ = ".".join(map(str, __version_info__)) diff --git a/contrib/python/hypothesis/py3/ya.make b/contrib/python/hypothesis/py3/ya.make index c07c5f7974..5da3870659 100644 --- a/contrib/python/hypothesis/py3/ya.make +++ b/contrib/python/hypothesis/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(6.98.5) +VERSION(6.98.6) LICENSE(MPL-2.0) |