mirror of
				https://github.com/searxng/searxng.git
				synced 2025-11-03 19:17:07 -05:00 
			
		
		
		
	[fix:py3.14] using a non-empty mutable collection as default is unsafe
Starting with Python 3.14 msgspec reports::
    File "/share/searxng/searx/weather.py", line 261, in <module>
        class Temperature(msgspec.Struct, kw_only=True):
        ...<60 lines>...
                return template.format(value=val_str, unit=unit)
    TypeError: Using a non-empty mutable collection (['°C', '°F', 'K']) \
               as a default value is unsafe.\
               Instead configure a `default_factory` for this field.
The problem is solved by the fact that there are now global constants for the
units (BTW singular/plural names of the type definitions are fixed):
- TEMPERATURE_UNITS
- PRESSURE_UNITS
- WIND_SPEED_UNITS
- RELATIVE_HUMIDITY_UNITS
- COMPASS_POINTS
- COMPASS_UNITS
Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
			
			
This commit is contained in:
		
							parent
							
								
									8fdc59a760
								
							
						
					
					
						commit
						d16283d93a
					
				@ -255,7 +255,8 @@ class DateTime(msgspec.Struct):
 | 
				
			|||||||
        return babel.dates.format_date(self.datetime, format=fmt, locale=locale)
 | 
					        return babel.dates.format_date(self.datetime, format=fmt, locale=locale)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TemperatureUnits: t.TypeAlias = t.Literal["°C", "°F", "K"]
 | 
					TemperatureUnit: t.TypeAlias = t.Literal["°C", "°F", "K"]
 | 
				
			||||||
 | 
					TEMPERATURE_UNITS: t.Final[tuple[TemperatureUnit]] = t.get_args(TemperatureUnit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Temperature(msgspec.Struct, kw_only=True):
 | 
					class Temperature(msgspec.Struct, kw_only=True):
 | 
				
			||||||
@ -263,19 +264,19 @@ class Temperature(msgspec.Struct, kw_only=True):
 | 
				
			|||||||
    measured values."""
 | 
					    measured values."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    val: float
 | 
					    val: float
 | 
				
			||||||
    unit: TemperatureUnits
 | 
					    unit: TemperatureUnit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    si_name: t.ClassVar[str] = "Q11579"
 | 
					    si_name: t.ClassVar[str] = "Q11579"
 | 
				
			||||||
    units: t.ClassVar[list[str]] = list(t.get_args(TemperatureUnits))
 | 
					    UNITS: t.ClassVar[tuple[TemperatureUnit]] = TEMPERATURE_UNITS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __post_init__(self):
 | 
					    def __post_init__(self):
 | 
				
			||||||
        if self.unit not in self.units:
 | 
					        if self.unit not in self.UNITS:
 | 
				
			||||||
            raise ValueError(f"invalid unit: {self.unit}")
 | 
					            raise ValueError(f"invalid unit: {self.unit}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
        return self.l10n()
 | 
					        return self.l10n()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self, unit: TemperatureUnits) -> float:
 | 
					    def value(self, unit: TemperatureUnit) -> float:
 | 
				
			||||||
        if unit == self.unit:
 | 
					        if unit == self.unit:
 | 
				
			||||||
            return self.val
 | 
					            return self.val
 | 
				
			||||||
        si_val = convert_to_si(si_name=self.si_name, symbol=self.unit, value=self.val)
 | 
					        si_val = convert_to_si(si_name=self.si_name, symbol=self.unit, value=self.val)
 | 
				
			||||||
@ -283,7 +284,7 @@ class Temperature(msgspec.Struct, kw_only=True):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def l10n(
 | 
					    def l10n(
 | 
				
			||||||
        self,
 | 
					        self,
 | 
				
			||||||
        unit: TemperatureUnits | None = None,
 | 
					        unit: TemperatureUnit | None = None,
 | 
				
			||||||
        locale: babel.Locale | GeoLocation | None = None,
 | 
					        locale: babel.Locale | GeoLocation | None = None,
 | 
				
			||||||
        template: str = "{value} {unit}",
 | 
					        template: str = "{value} {unit}",
 | 
				
			||||||
        num_pattern: str = "#,##0",
 | 
					        num_pattern: str = "#,##0",
 | 
				
			||||||
@ -322,7 +323,8 @@ class Temperature(msgspec.Struct, kw_only=True):
 | 
				
			|||||||
        return template.format(value=val_str, unit=unit)
 | 
					        return template.format(value=val_str, unit=unit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PressureUnits: t.TypeAlias = t.Literal["Pa", "hPa", "cm Hg", "bar"]
 | 
					PressureUnit: t.TypeAlias = t.Literal["Pa", "hPa", "cm Hg", "bar"]
 | 
				
			||||||
 | 
					PRESSURE_UNITS: t.Final[tuple[PressureUnit]] = t.get_args(PressureUnit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Pressure(msgspec.Struct, kw_only=True):
 | 
					class Pressure(msgspec.Struct, kw_only=True):
 | 
				
			||||||
@ -330,19 +332,19 @@ class Pressure(msgspec.Struct, kw_only=True):
 | 
				
			|||||||
    measured values."""
 | 
					    measured values."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    val: float
 | 
					    val: float
 | 
				
			||||||
    unit: PressureUnits
 | 
					    unit: PressureUnit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    si_name: t.ClassVar[str] = "Q44395"
 | 
					    si_name: t.ClassVar[str] = "Q44395"
 | 
				
			||||||
    units: t.ClassVar[list[str]] = list(t.get_args(PressureUnits))
 | 
					    UNITS: t.ClassVar[tuple[PressureUnit]] = PRESSURE_UNITS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __post_init__(self):
 | 
					    def __post_init__(self):
 | 
				
			||||||
        if self.unit not in self.units:
 | 
					        if self.unit not in self.UNITS:
 | 
				
			||||||
            raise ValueError(f"invalid unit: {self.unit}")
 | 
					            raise ValueError(f"invalid unit: {self.unit}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
        return self.l10n()
 | 
					        return self.l10n()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self, unit: PressureUnits) -> float:
 | 
					    def value(self, unit: PressureUnit) -> float:
 | 
				
			||||||
        if unit == self.unit:
 | 
					        if unit == self.unit:
 | 
				
			||||||
            return self.val
 | 
					            return self.val
 | 
				
			||||||
        si_val = convert_to_si(si_name=self.si_name, symbol=self.unit, value=self.val)
 | 
					        si_val = convert_to_si(si_name=self.si_name, symbol=self.unit, value=self.val)
 | 
				
			||||||
@ -350,7 +352,7 @@ class Pressure(msgspec.Struct, kw_only=True):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def l10n(
 | 
					    def l10n(
 | 
				
			||||||
        self,
 | 
					        self,
 | 
				
			||||||
        unit: PressureUnits | None = None,
 | 
					        unit: PressureUnit | None = None,
 | 
				
			||||||
        locale: babel.Locale | GeoLocation | None = None,
 | 
					        locale: babel.Locale | GeoLocation | None = None,
 | 
				
			||||||
        template: str = "{value} {unit}",
 | 
					        template: str = "{value} {unit}",
 | 
				
			||||||
        num_pattern: str = "#,##0",
 | 
					        num_pattern: str = "#,##0",
 | 
				
			||||||
@ -367,7 +369,8 @@ class Pressure(msgspec.Struct, kw_only=True):
 | 
				
			|||||||
        return template.format(value=val_str, unit=unit)
 | 
					        return template.format(value=val_str, unit=unit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WindSpeedUnits: t.TypeAlias = t.Literal["m/s", "km/h", "kn", "mph", "mi/h", "Bft"]
 | 
					WindSpeedUnit: t.TypeAlias = t.Literal["m/s", "km/h", "kn", "mph", "mi/h", "Bft"]
 | 
				
			||||||
 | 
					WIND_SPEED_UNITS: t.Final[tuple[WindSpeedUnit]] = t.get_args(WindSpeedUnit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class WindSpeed(msgspec.Struct, kw_only=True):
 | 
					class WindSpeed(msgspec.Struct, kw_only=True):
 | 
				
			||||||
@ -382,19 +385,19 @@ class WindSpeed(msgspec.Struct, kw_only=True):
 | 
				
			|||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    val: float
 | 
					    val: float
 | 
				
			||||||
    unit: WindSpeedUnits
 | 
					    unit: WindSpeedUnit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    si_name: t.ClassVar[str] = "Q182429"
 | 
					    si_name: t.ClassVar[str] = "Q182429"
 | 
				
			||||||
    units: t.ClassVar[list[str]] = list(t.get_args(WindSpeedUnits))
 | 
					    UNITS: t.ClassVar[tuple[WindSpeedUnit]] = WIND_SPEED_UNITS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __post_init__(self):
 | 
					    def __post_init__(self):
 | 
				
			||||||
        if self.unit not in self.units:
 | 
					        if self.unit not in self.UNITS:
 | 
				
			||||||
            raise ValueError(f"invalid unit: {self.unit}")
 | 
					            raise ValueError(f"invalid unit: {self.unit}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
        return self.l10n()
 | 
					        return self.l10n()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self, unit: WindSpeedUnits) -> float:
 | 
					    def value(self, unit: WindSpeedUnit) -> float:
 | 
				
			||||||
        if unit == self.unit:
 | 
					        if unit == self.unit:
 | 
				
			||||||
            return self.val
 | 
					            return self.val
 | 
				
			||||||
        si_val = convert_to_si(si_name=self.si_name, symbol=self.unit, value=self.val)
 | 
					        si_val = convert_to_si(si_name=self.si_name, symbol=self.unit, value=self.val)
 | 
				
			||||||
@ -402,7 +405,7 @@ class WindSpeed(msgspec.Struct, kw_only=True):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def l10n(
 | 
					    def l10n(
 | 
				
			||||||
        self,
 | 
					        self,
 | 
				
			||||||
        unit: WindSpeedUnits | None = None,
 | 
					        unit: WindSpeedUnit | None = None,
 | 
				
			||||||
        locale: babel.Locale | GeoLocation | None = None,
 | 
					        locale: babel.Locale | GeoLocation | None = None,
 | 
				
			||||||
        template: str = "{value} {unit}",
 | 
					        template: str = "{value} {unit}",
 | 
				
			||||||
        num_pattern: str = "#,##0",
 | 
					        num_pattern: str = "#,##0",
 | 
				
			||||||
@ -419,7 +422,8 @@ class WindSpeed(msgspec.Struct, kw_only=True):
 | 
				
			|||||||
        return template.format(value=val_str, unit=unit)
 | 
					        return template.format(value=val_str, unit=unit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RelativeHumidityUnits: t.TypeAlias = t.Literal["%"]
 | 
					RelativeHumidityUnit: t.TypeAlias = t.Literal["%"]
 | 
				
			||||||
 | 
					RELATIVE_HUMIDITY_UNITS: t.Final[tuple[RelativeHumidityUnit]] = t.get_args(RelativeHumidityUnit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RelativeHumidity(msgspec.Struct):
 | 
					class RelativeHumidity(msgspec.Struct):
 | 
				
			||||||
@ -428,8 +432,12 @@ class RelativeHumidity(msgspec.Struct):
 | 
				
			|||||||
    val: float
 | 
					    val: float
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # there exists only one unit (%) --> set "%" as the final value (constant)
 | 
					    # there exists only one unit (%) --> set "%" as the final value (constant)
 | 
				
			||||||
    unit: t.ClassVar["t.Final[RelativeHumidityUnits]"] = "%"
 | 
					    unit: t.ClassVar[RelativeHumidityUnit] = "%"
 | 
				
			||||||
    units: t.ClassVar[list[str]] = list(t.get_args(RelativeHumidityUnits))
 | 
					    UNITS: t.ClassVar[tuple[RelativeHumidityUnit]] = RELATIVE_HUMIDITY_UNITS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __post_init__(self):
 | 
				
			||||||
 | 
					        if self.unit not in self.UNITS:
 | 
				
			||||||
 | 
					            raise ValueError(f"invalid unit: {self.unit}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
        return self.l10n()
 | 
					        return self.l10n()
 | 
				
			||||||
@ -457,20 +465,23 @@ CompassPoint: t.TypeAlias = t.Literal[
 | 
				
			|||||||
    "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"
 | 
					    "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW"
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
"""Compass point type definition"""
 | 
					"""Compass point type definition"""
 | 
				
			||||||
 | 
					COMPASS_POINTS: t.Final[tuple[CompassPoint]] = t.get_args(CompassPoint)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CompassUnits: t.TypeAlias = t.Literal["°", "Point"]
 | 
					CompassUnit: t.TypeAlias = t.Literal["°", "Point"]
 | 
				
			||||||
 | 
					COMPASS_UNITS: t.Final[tuple[CompassUnit]] = t.get_args(CompassUnit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Compass(msgspec.Struct):
 | 
					class Compass(msgspec.Struct):
 | 
				
			||||||
    """Class for converting compass points and azimuth values (360°)"""
 | 
					    """Class for converting compass points and azimuth values (360°)"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    val: "float | int | CompassPoint"
 | 
					    val: "float | int | CompassPoint"
 | 
				
			||||||
    unit: CompassUnits = "°"
 | 
					    unit: CompassUnit = "°"
 | 
				
			||||||
 | 
					    UNITS: t.ClassVar[tuple[CompassUnit]] = COMPASS_UNITS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    TURN: t.ClassVar[float] = 360.0
 | 
					    TURN: t.ClassVar[float] = 360.0
 | 
				
			||||||
    """Full turn (360°)"""
 | 
					    """Full turn (360°)"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    POINTS: t.ClassVar[list[CompassPoint]] = list(t.get_args(CompassPoint))
 | 
					    POINTS: t.ClassVar[tuple[CompassPoint]] = COMPASS_POINTS
 | 
				
			||||||
    """Compass points."""
 | 
					    """Compass points."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    RANGE: t.ClassVar[float] = TURN / len(POINTS)
 | 
					    RANGE: t.ClassVar[float] = TURN / len(POINTS)
 | 
				
			||||||
@ -488,7 +499,7 @@ class Compass(msgspec.Struct):
 | 
				
			|||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
        return self.l10n()
 | 
					        return self.l10n()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self, unit: CompassUnits):
 | 
					    def value(self, unit: CompassUnit):
 | 
				
			||||||
        if unit == "Point" and isinstance(self.val, float):
 | 
					        if unit == "Point" and isinstance(self.val, float):
 | 
				
			||||||
            return self.point(self.val)
 | 
					            return self.point(self.val)
 | 
				
			||||||
        if unit == "°":
 | 
					        if unit == "°":
 | 
				
			||||||
@ -507,7 +518,7 @@ class Compass(msgspec.Struct):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def l10n(
 | 
					    def l10n(
 | 
				
			||||||
        self,
 | 
					        self,
 | 
				
			||||||
        unit: CompassUnits = "Point",
 | 
					        unit: CompassUnit = "Point",
 | 
				
			||||||
        locale: babel.Locale | GeoLocation | None = None,
 | 
					        locale: babel.Locale | GeoLocation | None = None,
 | 
				
			||||||
        template: str = "{value}{unit}",
 | 
					        template: str = "{value}{unit}",
 | 
				
			||||||
        num_pattern: str = "#,##0",
 | 
					        num_pattern: str = "#,##0",
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user