+
    Ki.  c                   s    R t ^ RIt^ RIt^ RIHt ^ RIHtHtHtH	t	 ^ RI
HtHt ^ RIHtHt ^ RIHt ^ RIHt ^ RIHtHt R	 R
 ltR R ltR R ltR R lt ! R R4      tR# )z9Handle the game, runner and global system configurations.N)copyfile)AnyDictOptionalSet)settings
sysoptions)InvalidRunnerErrorimport_runner)logger)path_exists)read_yaml_from_filewrite_yaml_to_filec                s0    V ^8  d   QhR\         R\         /# )   	game_slugreturnstrformat   "2/usr/lib/python3.14/site-packages/lutris/config.py__annotate__r      s     7 73 73 7    c                s^    RP                  V \        \        P                  ! 4       4      4      # )zBReturn an unique config id to avoid clashes between multiple gamesz{}-{})r   Zinttime)r      &r   make_game_config_idr      s    >>)S%566r   c                s^    V ^8  d   QhR\         R\        \         \        3,          R\         /# )r   r   configr   r   r   r   r   r   r   r   r      s)       d38n  r   c                s    \        V 4      p\        P                  ! RV4       \        P                  P                  \        P                  RV,          4      p\        W4       V# )zWrites a game config to diskzWriting game config to %sgames/%s.yml)	r   r	   debugospathjoinr   
CONFIG_DIRr   )r   r   Z
configpathZconfig_filenames   &&  r   write_game_configr#      sH    $Y/J
LL,j9ggll8#6#68STOv/r   c                s<    V ^8  d   QhR\         R\         R\         /# )r   r   source_config_idr   r   r   r   r   r   r      s!      S C C r   c                s   \        V 4      p\        P                  P                  \        P
                  RV,          4      p\        P                  P                  \        P
                  RV,          4      p\        W44       V# )zUCopies an existing configuration file, giving it a new id that this
function returns.r   )r   r   r    r!   r   r"   r    )r   r$   new_config_idsrc_path	dest_path   &&   r   duplicate_game_configr)      s[     (	2Mww||H//BR1RSHX00.=2PQIX!r   c                sR    V ^8  d   QhR\         R\         R\        \         ,          /# )r   old_config_idnew_slugr   )r   r   r   r   r   r   r   '   s%         r   c                 s    V P                  R ^4      w  r#W!8X  d   R# V R V 2p\        P                   RV  R2p\        P                   RV R2p\        P                  ! WV4       V# )Z-NZ/z.yml)Zrsplitr   ZGAME_CONFIG_DIRr   Zrename)r*   r+   Zold_slugZ	timestampr%   r&   r'   s   &&     r   rename_configr,   '   st    '..sA6Hj)-M**+1]O4@H++,Am_DAIIIh"r   c                   s$  a  ] tR t^2t o RtRV 3R lR lltR t]V 3R lR l4       t]V 3R lR	 l4       t	]V 3R
 lR l4       t
V 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltRtV tR# )LutrisConfiga  Class where all the configuration handling happens.

Description
===========
Lutris' configuration uses a cascading mechanism where
each higher, more specific level overrides the lower ones

The levels are (highest to lowest): `game`, `runner` and `system`.
Each level has its own set of options (config section), available to and
overridden by upper levels:
```
 level | Config sections
-------|----------------------
  game | system, runner, game
runner | system, runner
system | system
```
Example: if requesting runner options at game level, their returned value
will be from the game level config if it's set at this level; if not it
will be the value from runner level if available; and if not, the default
value set in the runner's module, or None.

The config levels are stored in separate YAML format text files.

Usage
=====
The config level will be auto set depending on what you pass to __init__:
- For game level, pass game_config_id and optionally runner_slug (better perfs)
- For runner level, pass runner_slug
- For system level, pass nothing
If need be, you can pass the level manually.

To read, use the config sections dicts: game_config, runner_config and
system_config.

To write, modify the relevant `raw_*_config` section dict, then run
`save()`.

Nc          
      s   < V ^8  d   QhRS[ S[,          RS[ S[,          RS[ S[,          RS[ S[S[,          ,          /# )r   runner_sluggame_config_idleveloptions_supported)r   r   r   r   __classdict__   "r   r   LutrisConfig.__annotate__[   sH     #! #!c]#! !#! }	#!
 $CH-#!r   c                sH   W n         V'       d   \        V4      V n        MWn        W@n        / V n        / V n        / V n        / V n        / V n        / V n	        / V n
        W0n        V'       g(   V'       d	   R V n        MV'       d	   RV n        MRV n        V P                  4        R# )gamerunnersystemN)r/   r   r.   r1   game_configrunner_configsystem_configraw_game_configraw_runner_configraw_system_config
raw_configr0   initialize_config)selfr.   r/   r0   r1   s   &&&&&r   __init__ZLutrisConfig.__init__[   s     -.1+.>D.9!2  "!#!# 
#
%
%
 r   c                s\    R V P                   : RV P                  : RV P                  : R2# )zLutrisConfig(level=z, game_config_id=z	, runner=Z))r0   r/   r.   rA   r   r   __repr__ZLutrisConfig.__repr__   s%    JJ
 	
r   c                s    < V ^8  d   QhRS[ /# r   r   r   r2   r4   r   r   r5      s     ? ?C ?r   c                s^    \         P                  P                  \        P                  R 4      # )z
system.yml)r   r    r!   r   r"   rC   r   r   system_config_pathZLutrisConfig.system_config_path   s    ww||H//>>r   c                0   < V ^8  d   QhRS[ S[,          /# rE   r   r   r2   r4   r   r   r5      s     V VHSM Vr   c                    V P                   '       g   R # \        P                  P                  \        P
                  RV P                   ,          4      # )Nz%s.yml)r.   r   r    r!   r   ZRUNNERS_CONFIG_DIRrC   r   r   runner_config_pathZLutrisConfig.runner_config_path   s7    ww||H77DDTDT9TUUr   c                rG   rE   rH   r2   r4   r   r   r5      s     W W(3- Wr   c                rI   )Nr   )r/   r   r    r!   r   r"   rC   r   r   game_config_pathZLutrisConfig.game_config_path   s7    """ww||H//$BUBU1UVVr   c                   < V ^8  d   QhRR/# r   r   N r2   r4   r   r   r5      s     ! !4 !r   c                s   R/ V P                   / R/ /V n        R/ V P                   / /V n        R/ /V n        V P                  '       d/   V P                  P                  \        V P                  4      4       V P                  '       d/   V P                  P                  \        V P                  4      4       V P                  P                  \        V P                  4      4       V P                  4        V P                  4        R# )zInit and load config filesr8   r6   N)r.   
game_levelrunner_levelsystem_levelrK   updater   rJ   rF   update_cascaded_configupdate_raw_configrC   r   r   r@   ZLutrisConfig.initialize_config   s    #R)9)92vrJ%r4+;+;R@%rN   OO""#6t7L7L#MN"""$$%89P9P%QR  !4T5L5L!MN##% r   c                rL   rM   rN   r2   r4   r   r   r5      s     G G Gr   c                s   V P                   P                  R 4      f   / V P                   R &   V P                  P                  4        V P                  P	                  V P                  R 4      4       V P                  P	                  V P                   P                  R / 4      4       V P                  R9   Ed-   V P                  '       Ed   V P                  P                  V P                  4      f   / V P                  V P                  &   V P                  P                  R 4      f   / V P                  R &   V P                  P                  4        V P                  P	                  V P                  R4      4       V P                  P	                  V P                  P                  V P                  / 4      4       V P                  V P                  P                  R 4      4       V P                  R8X  Ed   V P                  '       Ed}   V P                  P                  R4      f   / V P                  R&   V P                  P                  V P                  4      f   / V P                  V P                  &   V P                  P                  R 4      f   / V P                  R &   V P                  P                  4        V P                  P	                  V P                  R4      4       V P                  P	                  V P                  P                  R/ 4      4       V P                  P	                  V P                  P                  V P                  / 4      4       V P                  V P                  P                  R 4      4       R# R# R# )r8   Nr7   r6   r7   r6   )rQ   getr;   ZclearrR   get_defaultsr0   r.   rP   r:   merge_to_system_configrO   r9   rC   r   r   rS   Z#LutrisConfig.update_cascaded_config   s     *2*,Dh'  "!!$"3"3H"=>!!$"3"3"7"7""EF::++0@0@0@  $$T%5%56>68!!$"2"23  $$X.6.0!!(+$$&%%d&7&7&AB%%d&7&7&;&;D<L<Lb&QR''(9(9(=(=h(GH::D$4$4$4""6*2*,'""4#3#34<46 0 01""8,4,.)""$##D$5$5f$=>##DOO$7$7$CD%%doo&9&9$:J:JB&OP''(;(;H(EF %5r   c                sJ   < V ^8  d   QhRS[ S[S[S[3,          ,          RR/# )r   r   r   N)r   r   r   r   r2   r4   r   r   r5      s,     b bXd38n-E b$ br   c                s   V'       d   RpV P                   P                  R4      '       d   RV9   d   V P                   R,          pV P                   P                  V4       V'       d8   W P                   R&   V P                   R,          P                  VR,          4       RV P                   9   dO   V P                   R,          P                  4        UUu/ uF  w  r4V'       g   K  W4bK  	  uppV P                   R&   R# R# u uppi )z1Merge a configuration to the system configurationNZenv)r;   rV   rR   items)rA   r   Zexisting_envZkZvr(   r   rX   Z#LutrisConfig.merge_to_system_config   s    L!!%%e,,&#11%8%%f-,8""5)""5)00? D&&&:>:L:LU:S:Y:Y:[(a:[$!_`:[(aDu% '(as   D&Dc                rL   rM   rN   r2   r4   r   r   r5      s     % %4 %r   c                sh   V P                   R 8X  d   V P                  pM*V P                   R8X  d   V P                  pMV P                  pVR,          V n        V P                   R9   d&   V P
                  e   WP
                  ,          V n        V P                   R 8X  d   VR ,          V n        Wn        R# )r6   r7   r8   NrU   )	r0   rO   rP   rQ   r>   r.   r=   r<   r?   )rA   r?      & r   rT   ZLutrisConfig.update_raw_config   s    ::JZZ8#**J**J ",H!5::++0@0@0L%/0@0@%AD"::#-f#5D $r   c                rL   rM   rN   r2   r4   r   r   r5      s     A A Ar   c                s(   V P                   '       d   \        V P                   4      '       g$   \        P                  ! RV P                   4       R# \        P
                  ! V P                   4       \        P                  ! RV P                   4       R# )z(Delete the configuration file from disk.zNo config file at %sNzRemoved config %s)rK   r
   r	   r   r   removerC   r   r   r[   ZLutrisConfig.remove   s]    $$$K8M8M,N,NLL/1F1FG
		$''(($*?*?@r   c                rL   rM   rN   r2   r4   r   r   r5      s     ! !d !r   c                s~   V P                   e   \        R4      hV P                  R8X  d   V P                  pV P                  pMV P                  R8X  d,   V P
                  '       d   V P                  pV P
                  pMXV P                  R8X  d,   V P                  '       d   V P                  pV P                  pM\        RV P                  ,          4      hVP                  4        UUu/ uF  w  r4V'       g   K  W4bK  	  ppp\        P                  ! RW4       \        W4       V P                  4        R# u uppi )z-Save configuration file according to its typeNzOLutrisConfig instances that are restricted to only some options can't be saved.r8   r7   r6   zInvalid config level '%s'zSaving %s config to %s)r1   ZRuntimeErrorr0   rQ   rF   rJ   rP   rK   rO   Z
ValueErrorrY   r	   r   r   r@   )rA   r   Zconfig_pathZkeyZvalues   &    r   saveZLutrisConfig.save   s     !!-pqq::!&&F#66KZZ8#(?(?(?&&F11KZZ6!d&;&;&;__F//K84::EFF/5||~G~*#*~G-tA6/  Hs   +D9<D9c                <   < V ^8  d   QhRS[ RS[S[ S[3,          /# r   options_typer   r   r2   r4   r   r   r5     s#       c3h r   c                s^   V P                  V4      p/ pVP                  4        FU  w  rERV9   g   K  VR,          p\        V4      '       d*   V P                  e   W@P                  9   d
    V! 4       pMRpWcV&   KW  	  V#   \         d#   p\
        P                  ! RYG4        Rp?K  Rp?ii ; i)z(Return a dict of options' default value.defaultNz)Unable to generate a default for '%s': %s)options_as_dictrY   Zcallabler1   Z	Exceptionr	   Z	exception)rA   r_   Zoptions_dictZdefaultsoptionZparamsr`   Zexs   &&      r   rW   ZLutrisConfig.get_defaults  s    ++L9*002NFF" +G$$--5CYCY9Y%&-iG #'#*  3   ) %",,-XZ`e$%s   +A??B,
B''B,c                r]   r^   r   r2   r4   r   r   r5     s#     = =C =DcN =r   c                s   VR8X  dD   V P                   '       d!   \        P                  ! V P                   4      M\        P                  pMVV P                   '       g   / # VR,           p \	        V P                   4      p\        WC4      '       g   V! 4       p\        WC4      p\        R V 4       4      #   \         d    / p L!i ; i)z:Convert the option list to a dict with option name as keysr8   Z_optionsc              3   s6   "   T F  qR ,          V3x  K  	  R# 5i)rb   NrN   )Z.0ZoptrZ   r   Z	<genexpr>Z/LutrisConfig.options_as_dict.<locals>.<genexpr>,  s     <GS]C(Gs   )r.   r   Zwith_runner_overridesZsystem_optionsr   Zgetattrr   Zdict)rA   r_   ZoptionsZattribute_namer7   r(   r   ra   ZLutrisConfig.options_as_dict  s    8#FJFVFVFV
001A1AB\f\u\u  ###	)J6N:&t'7'78 v66#XF!&9<G<<< & s   )B3 3CC)r9   r/   rO   r0   r1   r?   r<   r=   r>   r:   rP   r.   r;   rQ   )NNNN)Z__name__Z
__module__Z__qualname__Z__firstlineno____doc__rB   rD   ZpropertyrF   rJ   rK   r@   rS   rX   rT   r[   r\   rW   ra   Z__static_attributes__Z__classdictcell__)r3   s   @r   r-   r-   2   s     &P#! #!J
 ? ? V V
 W W
! !G G<b b% %$A A! !. *= =r   r-   )rc   r   r   Zshutilr    Ztypingr   r   r   r   Zlutrisr   r   Zlutris.runnersr   r   Zlutris.util.logr	   Zlutris.util.systemr
   Zlutris.util.yamlr   r   r   r#   r)   r,   r-   rN   r   r   <module>rd      sF    ? 	   + + ' < " * D7
z= z=r   