Quantcast

Set a flag on the function or a global?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
37 messages Options
12
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

Steven D'Aprano-11
I have a function in a module which is intended to be used by importing
that name alone, then used interactively:

    from module import edir
    edir(args)


edir is an enhanced version of dir, and one of the enhancements is that
you can filter out dunder methods. I have reason to believe that people
are split on their opinion on whether dunder methods should be shown by
default or not: some people want to see them, others do not. Since edir
is meant to be used interactively, I want to give people a setting to
control whether they get dunders by default or not.

I have two ideas for this, a module-level global, or a flag set on the
function object itself. Remember that the usual way of using this will be
"from module import edir", there are two obvious ways to set the global:

import module
module.dunders = False

# -or-

edir.__globals__['dunders'] = False


Alternatively, I can use a flag set on the function object itself:

edir.dunders = False


Naturally you can always override the default by explicitly specifying a
keyword argument edir(obj, dunders=flag).

Thoughts and feedback? Please vote: a module global, or a flag on the
object? Please give reasons, and remember that the function is intended
for interactive use.


--
Steven D'Aprano

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

Chris Angelico
On Tue, Jun 16, 2015 at 9:57 AM, Steven D'Aprano
<steve+comp.lang.python at pearwood.info> wrote:

> I have two ideas for this, a module-level global, or a flag set on the
> function object itself. Remember that the usual way of using this will be
> "from module import edir", there are two obvious ways to set the global:
>
> import module
> module.dunders = False
>
> # -or-
>
> edir.__globals__['dunders'] = False
>
>
> Alternatively, I can use a flag set on the function object itself:
>
> edir.dunders = False
>

For most situations, the last one is extremely surprising - attributes
on functions aren't normally meant to be changed by outside callers,
it always feels wrong (they belong to the function itself). But since
this is interactive, I'd advise going for the absolute simplest, which
this would be. Go for the function attribute IMO.

ChrisA

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

Ethan Furman-2
In reply to this post by Steven D'Aprano-11
On 06/15/2015 04:57 PM, Steven D'Aprano wrote:

> Thoughts and feedback? Please vote: a module global, or a flag on the
> object? Please give reasons, and remember that the function is intended
> for interactive use.

Function attribute.

Setting a global on the module (which I may not have, and probably didn't, import) for only one function is overkill.

   edir.dunders = False # or True

is simple, elegant, easier to type, and perfectly in keeping with Python's dynamic nature.

--
~Ethan~

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

Ben Finney-10
In reply to this post by Chris Angelico
Chris Angelico <rosuav at gmail.com> writes:

> On Tue, Jun 16, 2015 at 9:57 AM, Steven D'Aprano
> <steve+comp.lang.python at pearwood.info> wrote:
> > I can use a flag set on the function object itself:
> >
> > edir.dunders = False
>
> For most situations, the last one is extremely surprising - attributes
> on functions aren't normally meant to be changed by outside callers,
> it always feels wrong (they belong to the function itself).

I'm surprised by your assertion. To my mind, outside callers get simple
and direct access to the attribute, whereas the code of the function
itself does not have such easy access; unlike ?self? for the current
instance of a class, there's no obvious name to use for referring to the
function object within the function object's own code.

In what sense do they ?belong to? the function itself *more than* to
outside callers?

--
 \       ?It's easy to play any musical instrument: all you have to do |
  `\       is touch the right key at the right time and the instrument |
_o__)                        will play itself.? ?Johann Sebastian Bach |
Ben Finney


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

Ethan Furman-2
In reply to this post by Chris Angelico
On 06/15/2015 05:07 PM, Chris Angelico wrote:
> On Tue, Jun 16, 2015 at 9:57 AM, Steven D'Aprano wrote:

>> I have two ideas for this, a module-level global, or a flag set on the
>> function object itself. Remember that the usual way of using this will be
>> "from module import edir", there are two obvious ways to set the global:
>>
>> import module
>> module.dunders = False
>>
>> # -or-
>>
>> edir.__globals__['dunders'] = False
>>
>>
>> Alternatively, I can use a flag set on the function object itself:
>>
>> edir.dunders = False
>>
>
> For most situations, the last one is extremely surprising - attributes
> on functions aren't normally meant to be changed by outside callers,

I find this viewpoint surprising, since function attributes are fairly rare.

> it always feels wrong (they belong to the function itself).

This seems silly -- a function is just another instance of some class.

--
~Ethan~

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

Ron Adam-2
In reply to this post by Chris Angelico


On 06/15/2015 08:07 PM, Chris Angelico wrote:

> On Tue, Jun 16, 2015 at 9:57 AM, Steven D'Aprano
> <steve+comp.lang.python at pearwood.info>  wrote:
>> >I have two ideas for this, a module-level global, or a flag set on the
>> >function object itself. Remember that the usual way of using this will be
>> >"from module import edir", there are two obvious ways to set the global:
>> >
>> >import module
>> >module.dunders = False
>> >
>> ># -or-
>> >
>> >edir.__globals__['dunders'] = False
>> >
>> >
>> >Alternatively, I can use a flag set on the function object itself:
>> >
>> >edir.dunders = False
>> >
> For most situations, the last one is extremely surprising - attributes
> on functions aren't normally meant to be changed by outside callers,

Or inside callers either.  You can't be sure of the name and there is no self.


> it always feels wrong (they belong to the function itself). But since
> this is interactive, I'd advise going for the absolute simplest, which
> this would be. Go for the function attribute IMO.


Another way is to make it an object with a __call__ method.

The the attribute can be accessed from both outside and inside dependably.

Cheers,
    Ron


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

sohcahtoa82@gmail.com
In reply to this post by Steven D'Aprano-11
On Monday, June 15, 2015 at 4:57:53 PM UTC-7, Steven D'Aprano wrote:

> I have a function in a module which is intended to be used by importing
> that name alone, then used interactively:
>
>     from module import edir
>     edir(args)
>
>
> edir is an enhanced version of dir, and one of the enhancements is that
> you can filter out dunder methods. I have reason to believe that people
> are split on their opinion on whether dunder methods should be shown by
> default or not: some people want to see them, others do not. Since edir
> is meant to be used interactively, I want to give people a setting to
> control whether they get dunders by default or not.
>
> I have two ideas for this, a module-level global, or a flag set on the
> function object itself. Remember that the usual way of using this will be
> "from module import edir", there are two obvious ways to set the global:
>
> import module
> module.dunders = False
>
> # -or-
>
> edir.__globals__['dunders'] = False
>
>
> Alternatively, I can use a flag set on the function object itself:
>
> edir.dunders = False
>
>
> Naturally you can always override the default by explicitly specifying a
> keyword argument edir(obj, dunders=flag).
>
> Thoughts and feedback? Please vote: a module global, or a flag on the
> object? Please give reasons, and remember that the function is intended
> for interactive use.
>
>
> --
> Steven D'Aprano

Using a keyword argument for the edir function is the most intuitive and easy to read, IMO.

Also, if two people are working on the same script, it could create problems if one person wants to filter them, but the other doesn't.  That would create a state that they would both have to monitor and keep setting back and forth, rather than each one just setting an argument on their calls.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

Chris Angelico
In reply to this post by Ben Finney-10
On Tue, Jun 16, 2015 at 10:20 AM, Ben Finney <ben+python at benfinney.id.au> wrote:

> Chris Angelico <rosuav at gmail.com> writes:
>
>> On Tue, Jun 16, 2015 at 9:57 AM, Steven D'Aprano
>> <steve+comp.lang.python at pearwood.info> wrote:
>> > I can use a flag set on the function object itself:
>> >
>> > edir.dunders = False
>>
>> For most situations, the last one is extremely surprising - attributes
>> on functions aren't normally meant to be changed by outside callers,
>> it always feels wrong (they belong to the function itself).
>
> I'm surprised by your assertion. To my mind, outside callers get simple
> and direct access to the attribute, whereas the code of the function
> itself does not have such easy access; unlike ?self? for the current
> instance of a class, there's no obvious name to use for referring to the
> function object within the function object's own code.
>
> In what sense do they ?belong to? the function itself *more than* to
> outside callers?

Custom function attributes (as in, those not set by the interpreter
itself) are pretty rare, but I've usually seen them only being defined
by the module that created them. Setting that kind of attribute
externally, from a different module, seems odd - and undiscoverable.
But for interactive work, that should be fine.

ChrisA

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

MRAB-2
In reply to this post by sohcahtoa82@gmail.com
On 2015-06-16 01:24, sohcahtoa82 at gmail.com wrote:

> On Monday, June 15, 2015 at 4:57:53 PM UTC-7, Steven D'Aprano wrote:
>> I have a function in a module which is intended to be used by
>> importing that name alone, then used interactively:
>>
>> from module import edir edir(args)
>>
>>
>> edir is an enhanced version of dir, and one of the enhancements is
>> that you can filter out dunder methods. I have reason to believe
>> that people are split on their opinion on whether dunder methods
>> should be shown by default or not: some people want to see them,
>> others do not. Since edir is meant to be used interactively, I want
>> to give people a setting to control whether they get dunders by
>> default or not.
>>
>> I have two ideas for this, a module-level global, or a flag set on
>> the function object itself. Remember that the usual way of using
>> this will be "from module import edir", there are two obvious ways
>> to set the global:
>>
>> import module module.dunders = False
>>
>> # -or-
>>
>> edir.__globals__['dunders'] = False
>>
>>
>> Alternatively, I can use a flag set on the function object itself:
>>
>> edir.dunders = False
>>
>>
>> Naturally you can always override the default by explicitly
>> specifying a keyword argument edir(obj, dunders=flag).
>>
>> Thoughts and feedback? Please vote: a module global, or a flag on
>> the object? Please give reasons, and remember that the function is
>> intended for interactive use.
>>
>>
>> -- Steven D'Aprano
>
> Using a keyword argument for the edir function is the most intuitive
> and easy to read, IMO.
>
> Also, if two people are working on the same script, it could create
> problems if one person wants to filter them, but the other doesn't.
> That would create a state that they would both have to monitor and
> keep setting back and forth, rather than each one just setting an
> argument on their calls.
>
But it's meant to be used interactively. If they're using it in a
script, they'd most likely set the argument appropriately.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

Paul Rubin-7
In reply to this post by Steven D'Aprano-11
Steven D'Aprano <steve+comp.lang.python at pearwood.info> writes:
> Thoughts and feedback? Please vote: a module global, or a flag on the
> object? Please give reasons, and remember that the function is intended
> for interactive use.

Both are bad.  More state to remember, ugh.  Instead have separate entry
points for filtering or not filtering the dunders.  Something like:

  edir(obj) = no dunders
  edir_(obj) = dunders.  

If you also support the keyword arg, then you could have

  edir_(obj)=functools.partial(edir,dunders=True).

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

Ethan Furman-2
On 06/15/2015 05:37 PM, Paul Rubin wrote:

> Steven D'Aprano <steve+comp.lang.python at pearwood.info> writes:
>> Thoughts and feedback? Please vote: a module global, or a flag on the
>> object? Please give reasons, and remember that the function is intended
>> for interactive use.
>
> Both are bad.  More state to remember, ugh.  Instead have separate entry
> points for filtering or not filtering the dunders.  Something like:
>
>    edir(obj) = no dunders
>    edir_(obj) = dunders.

`edir_` ?  What a horrible name.  I hate trailing underscores.  Too easy to miss.

--
~Ethan~

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

MRAB-2
On 2015-06-16 01:53, Ethan Furman wrote:

> On 06/15/2015 05:37 PM, Paul Rubin wrote:
>> Steven D'Aprano <steve+comp.lang.python at pearwood.info> writes:
>>> Thoughts and feedback? Please vote: a module global, or a flag on the
>>> object? Please give reasons, and remember that the function is intended
>>> for interactive use.
>>
>> Both are bad.  More state to remember, ugh.  Instead have separate entry
>> points for filtering or not filtering the dunders.  Something like:
>>
>>    edir(obj) = no dunders
>>    edir_(obj) = dunders.
>
> `edir_` ?  What a horrible name.  I hate trailing underscores.  Too easy to miss.
>
Especially when there's also `edir`! :-)


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

Paul Rubin-7
In reply to this post by Paul Rubin-7
Ethan Furman <ethan at stoneleaf.us> writes:
>>    edir_(obj) = dunders.
> `edir_` ?  What a horrible name.  I hate trailing underscores.  Too easy to miss.

They've worked ok for me at various times.  edir_u (for unfiltered) is
another idea.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

Mark Lawrence
In reply to this post by Steven D'Aprano-11
On 16/06/2015 00:57, Steven D'Aprano wrote:

> I have a function in a module which is intended to be used by importing
> that name alone, then used interactively:
>
>      from module import edir
>      edir(args)
>
>
> edir is an enhanced version of dir, and one of the enhancements is that
> you can filter out dunder methods. I have reason to believe that people
> are split on their opinion on whether dunder methods should be shown by
> default or not: some people want to see them, others do not. Since edir
> is meant to be used interactively, I want to give people a setting to
> control whether they get dunders by default or not.
>
> I have two ideas for this, a module-level global, or a flag set on the
> function object itself. Remember that the usual way of using this will be
> "from module import edir", there are two obvious ways to set the global:
>
> import module
> module.dunders = False
>
> # -or-
>
> edir.__globals__['dunders'] = False
>
>
> Alternatively, I can use a flag set on the function object itself:
>
> edir.dunders = False
>
>
> Naturally you can always override the default by explicitly specifying a
> keyword argument edir(obj, dunders=flag).
>
> Thoughts and feedback? Please vote: a module global, or a flag on the
> object? Please give reasons, and remember that the function is intended
> for interactive use.
>
>

For interactive use I'd be perfectly happy with just the keyword
argument.  Why bother toggling something when I can explicitly set it in
the call each and every time?  If I have to choose it's a flag on the
object, just no competition.

--
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

Steven D'Aprano-11
In reply to this post by sohcahtoa82@gmail.com
On Tuesday 16 June 2015 10:35, MRAB wrote:

> On 2015-06-16 01:24, sohcahtoa82 at gmail.com wrote:

>> Using a keyword argument for the edir function is the most intuitive
>> and easy to read, IMO.

edir() has a keyword argument: edir(x, dunders=False) suppresses the return
of dunder names. But since the primary purpose of [e]dir is, in my opinion,
to be used interactively, needing to type an extra 15 characters to hide
dunders is too inconvenient.


>> Also, if two people are working on the same script, it could create
>> problems if one person wants to filter them, but the other doesn't.
>> That would create a state that they would both have to monitor and
>> keep setting back and forth, rather than each one just setting an
>> argument on their calls.
>>
> But it's meant to be used interactively. If they're using it in a
> script, they'd most likely set the argument appropriately.

Yes.

The primary use-case (at least *my* use-case, and hopefully others) is to
have "from module import edir as dir" in their Python startup file. That
means that when running interactively, they will get the enhanced version of
dir, but when running a script or an application they'll just get the
regular one.

(Ideally, the regular one will eventually gain the same superpowers as edir
has, but that's a discussion for another day.)

Besides, apart from the inspect module, which probably shouldn't, who uses
dir() programmatically?

(If you do, you'll be glad to hear that edir() behaves the same as regular
dir() by default.)


--
Steve


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

Steven D'Aprano-11
In reply to this post by Paul Rubin-7
On Tuesday 16 June 2015 10:37, Paul Rubin wrote:

> Steven D'Aprano <steve+comp.lang.python at pearwood.info> writes:
>> Thoughts and feedback? Please vote: a module global, or a flag on the
>> object? Please give reasons, and remember that the function is intended
>> for interactive use.
>
> Both are bad.  More state to remember, ugh.  Instead have separate entry
> points for filtering or not filtering the dunders.  Something like:
>
>   edir(obj) = no dunders
>   edir_(obj) = dunders.

I certainly wouldn't call it edir_ but I'd maybe call it edir2 or ddir
("Dunderless DIR") or just_like_builtin_dir_only_better. <wink>

Normally I would agree with you, as a matter of principle, functions which
differ only by an argument called as a constant, particular when that
argument is a flag, should be split into multiple functions.

That is, instead of foo(x, flag=True) and foo(x, flag=False), have foo(x)
and foo2(x).

One disadvantage of this, though, is that it may not be self-evident which
function does what. Who remembers the difference between all the os.exec*
functions? Speaking of which:

py> dir(os, 'exec*')
['execl', 'execle', 'execlp', 'execlpe', 'execv', 'execve', 'execvp',
'execvpe']


But in this case, because [e]dir is intended to be run interactively, I
think that the convenience of a single function is more important. Most
people will set the default setting to whatever they prefer and then 95% of
the time just use it as given, only occasionally giving the dunders keyword
argument when they need the opposite setting.

Or at least, that's how *I* use it.

--
Steve


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

Steven D'Aprano-11
In reply to this post by Chris Angelico
On Tuesday 16 June 2015 10:20, Ben Finney wrote:

> Chris Angelico <rosuav at gmail.com> writes:
>
>> On Tue, Jun 16, 2015 at 9:57 AM, Steven D'Aprano
>> <steve+comp.lang.python at pearwood.info> wrote:
>> > I can use a flag set on the function object itself:
>> >
>> > edir.dunders = False
>>
>> For most situations, the last one is extremely surprising - attributes
>> on functions aren't normally meant to be changed by outside callers,
>> it always feels wrong (they belong to the function itself).
>
> I'm surprised by your assertion. To my mind, outside callers get simple
> and direct access to the attribute, whereas the code of the function
> itself does not have such easy access; unlike ?self? for the current
> instance of a class, there's no obvious name to use for referring to the
> function object within the function object's own code.
>
> In what sense do they ?belong to? the function itself *more than* to
> outside callers?

I won't answer for Chris, but speaking for myself, I think that an attribute
attached to a function is very clearly "part of" the function object in a
way that a global is not.

A bare global gives no hint as to which function(s) it will affect:

dunders = True

We can simulate a namespace by giving the name a prefix:

edir_dunders = True
hasattr(edir, "dunders")  # False, despite the simulated namespace


but using a real namespace is much better:

edir.dunders = True
hasattr(edir, "dunders")  # True


But having said that, I think that especially in Python the implication here
is that such an attribute is public and intended for outsiders to at least
read, if not write.

Adding public attributes to functions is deliberately supported in Python,
but it is greatly under-utilized.


--
Steve


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

Steven D'Aprano-11
In reply to this post by Chris Angelico
On Tuesday 16 June 2015 10:24, Ron Adam wrote:

> Another way is to make it an object with a __call__ method.
>
> The the attribute can be accessed from both outside and inside dependably.

That's what functions are, objects with a __call__ method:


py> (lambda: None).__call__
<method-wrapper '__call__' of function object at 0xb7301a04>


One slight disadvantage is that functions don't take a "self" parameter by
default, which means they have to refer to themselves by name:

def spam():
    print spam.attr


Here's a fun hack:

py> from types import MethodType
py> def physician(func):
...     # As in, "Physician, Know Thyself" :-)
...     return MethodType(func, func)
...
py> @physician
... def spam(this, n):
...     return this.food * n
...
py> spam.__func__.food = "spam-and-eggs "
py> spam(3)
'spam-and-eggs spam-and-eggs spam-and-eggs '


Alas, you cannot write directly to the method object itself :-(



--
Steve


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

Steven D'Aprano-11
In reply to this post by Steven D'Aprano-11
On Tuesday 16 June 2015 16:06, Mark Lawrence wrote:

> On 16/06/2015 00:57, Steven D'Aprano wrote:
[...]

>> Naturally you can always override the default by explicitly specifying a
>> keyword argument edir(obj, dunders=flag).
>>
>> Thoughts and feedback? Please vote: a module global, or a flag on the
>> object? Please give reasons, and remember that the function is intended
>> for interactive use.
>>
>>
>
> For interactive use I'd be perfectly happy with just the keyword
> argument.  Why bother toggling something when I can explicitly set it in
> the call each and every time?  If I have to choose it's a flag on the
> object, just no competition.

The idea is to set the default behaviour: does edir(obj) display dunder
methods by default or not? I've found that many people don't want to see the
dunder methods, and find dir() less pleasant or useful because it shows
them. Others disagree and want to see them. So you can set the default
behaviour you want, and then only worry about giving an explicit argument
when you want the opposite.

There is no intention for people to toggle the flag between calls!

# don't do this!
edir.dunders = True
edir(x)
edir.dunders = False
edir(y)


# do this instead
edir.dunders = True  # if that is your preferred setting
edir(x)
edir(y, dunders=False)




--
Steve


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Set a flag on the function or a global?

Jonas Wielicki
In reply to this post by Steven D'Aprano-11
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512



On 16.06.2015 01:57, Steven D'Aprano wrote:

> Alternatively, I can use a flag set on the function object itself:
>
> edir.dunders = False
>
>
> Naturally you can always override the default by explicitly
> specifying a keyword argument edir(obj, dunders=flag).
>
> Thoughts and feedback? Please vote: a module global, or a flag on
> the object? Please give reasons, and remember that the function is
> intended for interactive use.

I like a flag on the object, and this would be my implementation:

```
def edir_impl():
    # implementation of edir
    pass

class Edir(object):
    def __init__(self):
        self.kwargs = {}

    def __getattr__(self, name):
        return self.kwargs[name]

    def __setattr__(self, name, value):
        self.kwargs[name] = value

    def __delattr__(self, name):
        del self.kwargs[name]

    def __call__(self, *args, **kwargs):
        kwargs_to_use = self.kwargs.copy()
        kwargs_to_use.update(kwargs)
        edir_impl(*args, **kwargs_to_use)

edir = Edir()
```
(untested, but you get the idea, hopefully)

This also allows to have several versions of edir around in a shell
with different default settings.

regards,
jwi
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQIcBAEBCgAGBQJVf/PLAAoJEMBiAyWXYliKFM4P/jf/ZDZFacrRuk29tNzNFjA2
6UT4GURF6UX+C129gGgaqxpDY9oD9herfUpqbFxfNWq4Rye9MX+xkv3uQUsP5BXE
G7VjrSC0qd1GmdwFxdIQEb1fa6LgMmOnnYe/sIw5XWF2Rtbkqlisw7ZO3YDsWT9d
cadoEh0ShFbM6z4MUDEd8tu6RQ/j61v906TwsVgY+4uI8WWOzqHumM7pkWHxP2ns
3b/2ijQJNNLwH3UfbPBo3YhJWt0c+ACzuxr5MamVHUJBZpNatcszti3mkn2CtDCb
m5Kc0gO0RxHVaHV4RWrjYlcllhysQ/zeAuOz1PHEqevlitj8z1cBy3p4sfz8GOZe
XAKChaZHVAq7eTGzgtLksBQ0dujLxy9zLWiHfeLfMnTyZoYFKVCM2rlSYutnkI0f
7VdaaKStVpqkXeJHX1n1LvHBOroQCFtUFn2F0FylpR/nBA7ar9epZYiCWbrb21xO
DYs8T7dC7DI1waLeXJ2JbXiXqh6cQ9Fy86fm+VE1lmkJ6LvboRCN9eWMQ1o1+RtM
Dla6CvH2zxgW2u3HZCIoU9TusYaNLR9kSxqCMc2yLuMiUQpj0HfjZCR+ZP2/9phS
wx+qZx+5X25ybXlCZRtlvzb409BclOJ7JOynboX4MU4M9sSCPJhb5/ZcM79r7nJa
o0y06nE5eReu71TMwmDW
=r9uV
-----END PGP SIGNATURE-----

12
Loading...