GIF89a=( õ' 7IAXKgNgYvYx\%wh…hŽth%ˆs%—x¨}9®Œ©€&©‰%¶†(¹–.¹5·œD¹&Çš)ÇŸ5ǘ;Í£*È¡&Õ²)ׯ7×µ<Ñ»4ï°3ø‘HÖ§KͯT÷¨Yÿšqÿ»qÿÔFØ !ù ' !ÿ NETSCAPE2.0 , =( þÀ“pH,È¤rÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§gª«ªE¯°¨¬ª±²Œ¹º¹E¾­”´ÂB¶¯ §Åȸ»ÑD¾¿Á•ÄÅ®° ÝH¾ÒLÀÆDÙ«D¶BÝïðÀ¾DÑÑÔTÌÍíH òGö¨A RÎڐ |¥ ٭&ºìE8œ¹kGÔAÞpx­a¶­ã R2XB®åE8I€Õ6Xî:vT)äžþÀq¦è³¥ì仕F~%xñ  4#ZÔ‰O|-4Bs‘X:= QÉ œš lºÒyXJŠGȦ|s hÏíK–3l7·B|¥$'7Jީܪ‰‡àá”Dæn=Pƒ ¤Òëí‰`䌨ljóá¯Éüv>á–Á¼5 ½.69ûϸd«­ºÀûnlv©‹ªîf{¬ÜãPbŸ  l5‘ޝpß ´ ˜3aÅùäI«O’ý·‘áÞ‡˜¾Æ‚ÙÏiÇÿ‹Àƒ #öó)pâš Þ½ ‘Ý{ó)vmÞü%D~ 6f s}ŃƒDØW Eþ`‡þ À…L8xá†ç˜{)x`X/> Ì}mø‚–RØ‘*|`D=‚Ø_ ^ð5 !_…'aä“OÚ—7âcð`D”Cx`ÝÂ¥ä‹éY¹—F¼¤¥Š?¡Õ™ n@`} lď’ÄÉ@4>ñd œ à‘vÒxNÃ×™@žd=ˆgsžG±æ ´²æud &p8Qñ)ˆ«lXD©øÜéAžHìySun jª×k*D¤LH] †¦§C™Jä–´Xb~ʪwStŽ6K,°£qÁœ:9ت:¨þªl¨@¡`‚ûÚ ».Û¬¯t‹ÆSÉ[:°=Š‹„‘Nåû”Ìî{¿ÂA ‡Rà›ÀÙ6úë°Ÿð0Ä_ ½;ÃϱîÉì^ÇÛÇ#Ëë¼ôº!±Ä˜íUîÅÇ;0L1óÁµö«p% AÀºU̬ݵ¼á%霼€‡¯Á~`ÏG¯»À× ­²± =4ªnpð3¾¤³¯­ü¾¦îuÙuµÙ®|%2ÊIÿür¦#0·ÔJ``8È@S@5ê¢ ö×Þ^`8EÜ]ý.뜃Âç 7 ú ȉÞj œ½Dç zý¸iþœÑÙûÄë!ˆÞÀl§Ïw‹*DçI€nEX¯¬¼ &A¬Go¼QföõFç°¯;é¦÷îŽêJ°îúôF5¡ÌQ|îúöXªæ»TÁÏyñêï]ê² o óÎC=öõ›ÒÓPB@ D×½œä(>èCÂxŽ`±«Ÿ–JЀ»Û á¤±p+eE0`ëŽ`A Ú/NE€Ø†À9‚@¤à H½7”à‡%B‰`Àl*ƒó‘–‡8 2ñ%¸ —€:Ù1Á‰E¸àux%nP1ð!‘ðC)¾P81lÑɸF#ˆ€{´âé°ÈB„0>±û °b¡Š´±O‚3È–Ù()yRpbµ¨E.Z‘D8ÊH@% òŒx+%Ù˜Æcü »¸˜fõ¬b·d`Fê™8èXH"ÉÈ-±|1Ô6iI, 2““¬$+](A*jÐ QTÂo‰.ÛU슬Œã„Ž`¯SN¡–¶Äåyše¯ª’­¬‚´b¦Éož œ)åyâ@Ì®3 ÎtT̉°&Ø+žLÀf"Ø-|žçÔ>‡Ðv¦Ðžì\‚ Q1)Ž@Žh#aP72”ˆ™¨$‚ !ù " , =( …7IAXG]KgNgYvYxR"k\%w]'}hŽth%ˆg+ˆs%—r.—m3šx3˜x¨}9®€&©€+¨‡7§‰%¶†(¹–.¹œD¹&ǘ;Í•&ײ)×»4ïÌ6ò§KÍ þ@‘pH,È¤rÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§g «¬ E ±± ¨­¶°ººE Á´”·®C¬²§Ç¶Œ»ÓDÃÕƷ¯Ê±H½ºM×ÁGÚ¬D¶BËÁ½î½DÓôTÏÛßîG»ôõC×CÌ l&âž:'òtU³6ɹ#·Ø)€'Ü.6±&ëÍÈ» K(8p0N?!æ2"ÛˆNIJX>R¼ÐO‚M '¡¨2¸*Ÿþ>#n↠å@‚<[:¡Iïf’ ¤TÚ˘CdbÜÙ“[«ŽEú5MBo¤×@€`@„€Êt W-3 ¶Ÿ¡BíêäjIÝ…Eò9[T…$íêﯧ„…•s»Óȳ¹€ÅÚdc®UUρ#±Ùïldj?´í¼²`\ŽÁðÞu|3'ÖŒ]ë6 ¶S#²‡˜FKLÈ *N E´‘áäŠ$˜›eÄYD„ºq«.è촁ƒs \-ÔjA 9²õ÷å- üúM[Âx(ís÷ì®x€|í¡Ù’p¦‚ ŽkÛTÇDpE@WÜ ²Ç]kŠ1¨ þ€·Yb ÓÁ‰l°*n0 ç™—žzBdОu¾7ĉBl€â‰-ºx~|UåU‰  h*Hœ|e"#"?vpÄiŠe6^ˆ„+qâŠm8 #VÇá ‘å–ÄV„œ|Аè•m"сœn|@›U¶ÆÎž—Špb¥G¨ED”€±Úê2FÌIç? >Éxå Œ± ¡¤„%‘žjŸ‘ꄯ<Ìaà9ijÐ2˜D¦È&›†Z`‚å]wþ¼Â:ç6àB¤7eFJ|õÒ§Õ,¨äàFÇ®cS·Ê¶+B°,‘Þ˜ºNûãØ>PADÌHD¹æž«ÄÀnÌ¥}­#Ë’ë QÀÉSÌÂÇ2ÌXÀ{æk²lQÁ2«ÊðÀ¯w|2Í h‹ÄÂG€,m¾¶ë3ÐÙ6-´ÅE¬L°ÆIij*K½ÀÇqï`DwVÍQXœÚÔpeœ±¬Ñ q˜§Tœ½µƒ°Œìu Â<¶aØ*At¯lmEØ ü ôÛN[P1ÔÛ¦­±$ÜÆ@`ùåDpy¶yXvCAyåB`ŽD¶ 0QwG#¯ æš[^Äþ $ÀÓÝǦ{„L™[±úKÄgÌ;ï£S~¹ìGX.ôgoT.»åˆ°ùŸûù¡?1zö¦Ÿž:ÅgÁ|ìL¹ „®£œŠ‚à0œ]PÁ^p F<"•ç?!,ñ‡N4—…PÄ Á„ö¨Û:Tè@hÀ‹%táÿ:ø-žI<`þ‹p I….)^ 40D#p@ƒj4–؀:²‰1Øâr˜¼F2oW¼#Z†;$Q q” ‘ ÂK¦ñNl#29 !’F@¥Bh·ᏀL!—XFóLH‘Kh¤.«hE&JòG¨¥<™WN!€ÑÙÚˆY„@†>Œž19J" 2,/ &.GXB%ÌRÈ9B6¹W]’î×ÔW¥’IÎ$ ñ‹ÓŒE8YÆ ¼³™ñA5“à®Q.aŸB€&Ø©³ JÁ—! ¦t)K%tœ-¦JF bòNMxLôþ)ÐR¸Ð™‘ èÝ6‘O!THÌ„HÛ ‰ !ù ) , =( …AXKgNgYvYxR"k\%wh…hŽh%ˆg+ˆs%—r.—x3˜x¨}9®€&©€+¨Œ,©‡7§‰%¶†(¹–.¹5·&Çš)ǘ;Í•&×£*Ȳ)ׯ7×»4ï°3øÌ6ò‘HÖ§KÍ»Hó¯T÷¨Yÿ»qÿÇhÿ þÀ”pH,È¤rÉl:ŸÐ¨tJ­Z¯Ø¬vËíz¿à°xL.›Ïè´zÍn»ßð¸|N¯Ûïø¼~Ïïûÿ€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§g ª« E$±²¨ª­ · °²½$E$ÂÕ««D· Í ¿¦Ç¶¸ÌŒ¾³CÃÅÆ E ééH½MÛÂGâªD­ çBêêϾD²ÒaÀà€Š1r­ðÓ¤ ÔožzU!L˜C'¾yW½UGtäÇïÙllê0×àÂuGþ)AÀs[þ·xì ÁxO%ƒûX2ó—  P£n›R/¡ÑšHše+êDm?# —‘Ç£6¡8íJ¡ŸâDiäªM¥Ö„ôj“¬¹£5oQ7°- <‡ *´lãÓŒ2r/a!l)dÈ A™ÈE¢ôÔ͆…ð ;Ö˜c ¡%ß‚’Ùˆâ¸b½—pe~C"BíëÚHïeF2§æŠ8qb t_`urŠeü wÅu3êæPv§h•"ß`íÍxçLĹÜÖ3á  ~Öº“®›¸ÏMDfJÙ °„ÛµáWõ%§œ‚à©–‚X ÓØ)@®Ñ›Eþ´wëuÅSxb8y\mÖzœ¥§ZbºE—ÂLªÌw!y(>¡™wú=Ç|ÅÝs¢d €CÁW)HÜcC$€L Ä7„r.á\{)@ð` @ äXÈ$PD” `šaG:§æˆOˆ72EÐamn]ù"ŒcÊxÑŒ° &dR8`g«iÙŸLR!¦P …d’ä¡“¦ðÎTƒ¦ià|À _ ¥ Qi#¦Šg›Æ ›noMµ ›V ã£)p ç£ÎW…š=Âeªk§†j„ ´®1ß²sÉxéW«jšl|0¯B0Û, \jÛ´›6±¬¶C ÛíWþï|ëÙ‹¸ñzĸV {ì;Ýñn¼òVˆm³I¼³.Ðã¤PN¥ ²µ¼„µCã+¹ÍByî£Ñ¾HŸ›ëê 7ìYÆFTk¨SaoaY$Dµœìï¿Ã29RÈkt Çïfñ ÇÒ:ÀÐSp¹3ÇI¨â¥DZÄ ü9Ïýögñ½­uÔ*3)O‘˜Ö[_hv ,àî×Et Ÿé¶BH€ Õ[ü±64M@ÔSÌM7dÐl5-ÄÙU܍´©zߌ3Ô€3ž„ „ ¶ÛPô½5×g› êÚ˜kN„Ý…0Îj4€Ìë°“#{þÕ3S2çKÜ'ợlø¼Ú2K{° {Û¶?žm𸧠ËI¼nEò='êüóºè^üæÃ_Û=°óž‚ì#Oý¿Í'¡½áo..ÏYìnüñCœO±Áa¿¢Kô½o,üÄËbö²çºíï{ËC Ú— "”Ï{ËK ÍÒw„õ±Oz dÕ¨à:$ ƒô—«v»] A#ð «€¿šéz)Rx׿ˆ¥‚d``èw-îyÏf×K!ð€þ­Ð|ìPľ„=Ì`ý(f” 'Pa ¥ÐBJa%Ðâf§„%Š¡}FàáÝ×6>ÉäŠG"éŽè=ø!oа^FP¼Ø©Q„ÀCÙÁ`(Ž\ÄÝ® ©Â$<n@dÄ E#ììUÒI! ‚#lù‹`k¦ÐÇ'Rró’ZýNBÈMF Í[¤+‹ðɈ-áwj¨¥þ8¾rá ,VÂh„"|½œ=×G_¦Ñ™EØ 0i*%̲˜Æda0mV‚k¾)›;„&6 p>ÓjK “¦Ç# âDÂ:ûc?:R Ó¬fÞéI-Ì“•Ã<ä=™Ï7˜3œ¨˜c2ŒW ,ˆ”8(T™P‰F¡Jhç"‚ ; 403WebShell
403Webshell
Server IP : 104.21.83.152  /  Your IP : 216.73.216.195
Web Server : LiteSpeed
System : Linux premium229.web-hosting.com 4.18.0-553.45.1.lve.el8.x86_64 #1 SMP Wed Mar 26 12:08:09 UTC 2025 x86_64
User : akhalid ( 749)
PHP Version : 8.3.22
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /opt/hc_python/lib/python3.12/site-packages/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /opt/hc_python/lib/python3.12/site-packages/cfgv.py
from __future__ import annotations

import collections
import contextlib
import os.path
import re
import sys


class ValidationError(ValueError):
    def __init__(self, error_msg, ctx=None):
        super().__init__(error_msg)
        self.error_msg = error_msg
        self.ctx = ctx

    def __str__(self):
        out = '\n'
        err = self
        while err.ctx is not None:
            out += f'==> {err.ctx}\n'
            err = err.error_msg
        out += f'=====> {err.error_msg}'
        return out


MISSING = collections.namedtuple('Missing', ())()
type(MISSING).__repr__ = lambda self: 'MISSING'


@contextlib.contextmanager
def validate_context(msg):
    try:
        yield
    except ValidationError as e:
        _, _, tb = sys.exc_info()
        raise ValidationError(e, ctx=msg).with_traceback(tb) from None


@contextlib.contextmanager
def reraise_as(tp):
    try:
        yield
    except ValidationError as e:
        _, _, tb = sys.exc_info()
        raise tp(e).with_traceback(tb) from None


def _dct_noop(self, dct):
    pass


def _check_optional(self, dct):
    if self.key not in dct:
        return
    with validate_context(f'At key: {self.key}'):
        self.check_fn(dct[self.key])


def _apply_default_optional(self, dct):
    dct.setdefault(self.key, self.default)


def _remove_default_optional(self, dct):
    if dct.get(self.key, MISSING) == self.default:
        del dct[self.key]


def _require_key(self, dct):
    if self.key not in dct:
        raise ValidationError(f'Missing required key: {self.key}')


def _check_required(self, dct):
    _require_key(self, dct)
    _check_optional(self, dct)


@property
def _check_fn_recurse(self):
    def check_fn(val):
        validate(val, self.schema)
    return check_fn


def _apply_default_required_recurse(self, dct):
    dct[self.key] = apply_defaults(dct[self.key], self.schema)


def _remove_default_required_recurse(self, dct):
    dct[self.key] = remove_defaults(dct[self.key], self.schema)


def _apply_default_optional_recurse(self, dct):
    if self.key not in dct:
        _apply_default_optional(self, dct)
    _apply_default_required_recurse(self, dct)


def _remove_default_optional_recurse(self, dct):
    if self.key in dct:
        _remove_default_required_recurse(self, dct)
        _remove_default_optional(self, dct)


def _get_check_conditional(inner):
    def _check_conditional(self, dct):
        if dct.get(self.condition_key, MISSING) == self.condition_value:
            inner(self, dct)
        elif (
                self.condition_key in dct and
                self.ensure_absent and self.key in dct
        ):
            if hasattr(self.condition_value, 'describe_opposite'):
                explanation = self.condition_value.describe_opposite()
            else:
                explanation = f'is not {self.condition_value!r}'
            raise ValidationError(
                f'Expected {self.key} to be absent when {self.condition_key} '
                f'{explanation}, found {self.key}: {dct[self.key]!r}',
            )
    return _check_conditional


def _apply_default_conditional_optional(self, dct):
    if dct.get(self.condition_key, MISSING) == self.condition_value:
        _apply_default_optional(self, dct)


def _remove_default_conditional_optional(self, dct):
    if dct.get(self.condition_key, MISSING) == self.condition_value:
        _remove_default_optional(self, dct)


def _apply_default_conditional_recurse(self, dct):
    if dct.get(self.condition_key, MISSING) == self.condition_value:
        _apply_default_required_recurse(self, dct)


def _remove_default_conditional_recurse(self, dct):
    if dct.get(self.condition_key, MISSING) == self.condition_value:
        _remove_default_required_recurse(self, dct)


def _no_additional_keys_check(self, dct):
    extra = sorted(set(dct) - set(self.keys))
    if extra:
        extra_s = ', '.join(str(x) for x in extra)
        keys_s = ', '.join(str(x) for x in self.keys)
        raise ValidationError(
            f'Additional keys found: {extra_s}.  '
            f'Only these keys are allowed: {keys_s}',
        )


def _warn_additional_keys_check(self, dct):
    extra = sorted(set(dct) - set(self.keys))
    if extra:
        self.callback(extra, self.keys, dct)


Required = collections.namedtuple('Required', ('key', 'check_fn'))
Required.check = _check_required
Required.apply_default = _dct_noop
Required.remove_default = _dct_noop
RequiredRecurse = collections.namedtuple('RequiredRecurse', ('key', 'schema'))
RequiredRecurse.check = _check_required
RequiredRecurse.check_fn = _check_fn_recurse
RequiredRecurse.apply_default = _apply_default_required_recurse
RequiredRecurse.remove_default = _remove_default_required_recurse
Optional = collections.namedtuple('Optional', ('key', 'check_fn', 'default'))
Optional.check = _check_optional
Optional.apply_default = _apply_default_optional
Optional.remove_default = _remove_default_optional
OptionalRecurse = collections.namedtuple(
    'OptionalRecurse', ('key', 'schema', 'default'),
)
OptionalRecurse.check = _check_optional
OptionalRecurse.check_fn = _check_fn_recurse
OptionalRecurse.apply_default = _apply_default_optional_recurse
OptionalRecurse.remove_default = _remove_default_optional_recurse
OptionalNoDefault = collections.namedtuple(
    'OptionalNoDefault', ('key', 'check_fn'),
)
OptionalNoDefault.check = _check_optional
OptionalNoDefault.apply_default = _dct_noop
OptionalNoDefault.remove_default = _dct_noop
Conditional = collections.namedtuple(
    'Conditional',
    ('key', 'check_fn', 'condition_key', 'condition_value', 'ensure_absent'),
)
Conditional.__new__.__defaults__ = (False,)
Conditional.check = _get_check_conditional(_check_required)
Conditional.apply_default = _dct_noop
Conditional.remove_default = _dct_noop
ConditionalOptional = collections.namedtuple(
    'ConditionalOptional',
    (
        'key', 'check_fn', 'default', 'condition_key', 'condition_value',
        'ensure_absent',
    ),
)
ConditionalOptional.__new__.__defaults__ = (False,)
ConditionalOptional.check = _get_check_conditional(_check_optional)
ConditionalOptional.apply_default = _apply_default_conditional_optional
ConditionalOptional.remove_default = _remove_default_conditional_optional
ConditionalRecurse = collections.namedtuple(
    'ConditionalRecurse',
    ('key', 'schema', 'condition_key', 'condition_value', 'ensure_absent'),
)
ConditionalRecurse.__new__.__defaults__ = (False,)
ConditionalRecurse.check = _get_check_conditional(_check_required)
ConditionalRecurse.check_fn = _check_fn_recurse
ConditionalRecurse.apply_default = _apply_default_conditional_recurse
ConditionalRecurse.remove_default = _remove_default_conditional_recurse
NoAdditionalKeys = collections.namedtuple('NoAdditionalKeys', ('keys',))
NoAdditionalKeys.check = _no_additional_keys_check
NoAdditionalKeys.apply_default = _dct_noop
NoAdditionalKeys.remove_default = _dct_noop
WarnAdditionalKeys = collections.namedtuple(
    'WarnAdditionalKeys', ('keys', 'callback'),
)
WarnAdditionalKeys.check = _warn_additional_keys_check
WarnAdditionalKeys.apply_default = _dct_noop
WarnAdditionalKeys.remove_default = _dct_noop


class Map(collections.namedtuple('Map', ('object_name', 'id_key', 'items'))):
    __slots__ = ()

    def __new__(cls, object_name, id_key, *items):
        return super().__new__(cls, object_name, id_key, items)

    def check(self, v):
        if not isinstance(v, dict):
            raise ValidationError(
                f'Expected a {self.object_name} map but got a '
                f'{type(v).__name__}',
            )
        if self.id_key is None:
            context = f'At {self.object_name}()'
        else:
            key_v_s = v.get(self.id_key, MISSING)
            context = f'At {self.object_name}({self.id_key}={key_v_s!r})'
        with validate_context(context):
            for item in self.items:
                item.check(v)

    def apply_defaults(self, v):
        ret = v.copy()
        for item in self.items:
            item.apply_default(ret)
        return ret

    def remove_defaults(self, v):
        ret = v.copy()
        for item in self.items:
            item.remove_default(ret)
        return ret


class Array(collections.namedtuple('Array', ('of', 'allow_empty'))):
    __slots__ = ()

    def __new__(cls, of, allow_empty=True):
        return super().__new__(cls, of=of, allow_empty=allow_empty)

    def check(self, v):
        check_array(check_any)(v)
        if not self.allow_empty and not v:
            raise ValidationError(
                f"Expected at least 1 '{self.of.object_name}'",
            )
        for val in v:
            validate(val, self.of)

    def apply_defaults(self, v):
        return [apply_defaults(val, self.of) for val in v]

    def remove_defaults(self, v):
        return [remove_defaults(val, self.of) for val in v]


class Not(collections.namedtuple('Not', ('val',))):
    __slots__ = ()

    def describe_opposite(self):
        return f'is {self.val!r}'

    def __eq__(self, other):
        return other is not MISSING and other != self.val


class NotIn(collections.namedtuple('NotIn', ('values',))):
    __slots__ = ()

    def __new__(cls, *values):
        return super().__new__(cls, values=values)

    def describe_opposite(self):
        return f'is any of {self.values!r}'

    def __eq__(self, other):
        return other is not MISSING and other not in self.values


class In(collections.namedtuple('In', ('values',))):
    __slots__ = ()

    def __new__(cls, *values):
        return super().__new__(cls, values=values)

    def describe_opposite(self):
        return f'is not any of {self.values!r}'

    def __eq__(self, other):
        return other is not MISSING and other in self.values


def check_any(_):
    pass


def check_type(tp, typename=None):
    def check_type_fn(v):
        if not isinstance(v, tp):
            typename_s = typename or tp.__name__
            raise ValidationError(
                f'Expected {typename_s} got {type(v).__name__}',
            )
    return check_type_fn


check_bool = check_type(bool)
check_bytes = check_type(bytes)
check_int = check_type(int)
check_string = check_type(str, typename='string')
check_text = check_type(str, typename='text')


def check_one_of(possible):
    def check_one_of_fn(v):
        if v not in possible:
            possible_s = ', '.join(str(x) for x in sorted(possible))
            raise ValidationError(
                f'Expected one of {possible_s} but got: {v!r}',
            )
    return check_one_of_fn


def check_regex(v):
    try:
        re.compile(v)
    except re.error:
        raise ValidationError(f'{v!r} is not a valid python regex')


def check_array(inner_check):
    def check_array_fn(v):
        if not isinstance(v, (list, tuple)):
            raise ValidationError(
                f'Expected array but got {type(v).__name__!r}',
            )

        for i, val in enumerate(v):
            with validate_context(f'At index {i}'):
                inner_check(val)
    return check_array_fn


def check_and(*fns):
    def check(v):
        for fn in fns:
            fn(v)
    return check


def validate(v, schema):
    schema.check(v)
    return v


def apply_defaults(v, schema):
    return schema.apply_defaults(v)


def remove_defaults(v, schema):
    return schema.remove_defaults(v)


def load_from_filename(
        filename,
        schema,
        load_strategy,
        exc_tp=ValidationError,
        *,
        display_filename=None,
):
    display_filename = display_filename or filename
    with reraise_as(exc_tp):
        if not os.path.isfile(filename):
            raise ValidationError(f'{display_filename} is not a file')

        with validate_context(f'File {display_filename}'):
            try:
                with open(filename, encoding='utf-8') as f:
                    contents = f.read()
            except UnicodeDecodeError as e:
                raise ValidationError(str(e))

            try:
                data = load_strategy(contents)
            except Exception as e:
                raise ValidationError(str(e))

            validate(data, schema)
            return apply_defaults(data, schema)

Youez - 2016 - github.com/yon3zu
LinuXploit