Re: [Python-Dev] PEP 514: Python registration in the Windows registry

2016-07-19 Thread Paul Moore
On 18 July 2016 at 18:01, Paul Moore  wrote:
> On 18 July 2016 at 17:33, Steve Dower  wrote:
>>> Some comments below.
>>
>> Awesome, thanks! Posted a pull request at
>> https://github.com/python/peps/pull/59 for ease of diff reading, and some
>> commentary below (with aggressive snipping).
>
> Thanks - I'll do a proper review of that, but just wanted to make a
> few comments here.

Added some comments to the PR. Basically:

1. We could do with a better descrition of use cases.
2. We either require registry keys to be user-friendly (no UUIDs!) or
we find an alternative approach for the virtualenv-style use case.
3. Registering "how to start the interpreter" (python.exe or whatever)
should be mandatory.

I don't think we're far off, though.

Paul
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 514: Python registration in the Windows registry

2016-07-19 Thread Paul Moore
On 19 July 2016 at 10:49, Paul Moore  wrote:
> On 18 July 2016 at 18:01, Paul Moore  wrote:
>> On 18 July 2016 at 17:33, Steve Dower  wrote:
 Some comments below.
>>>
>>> Awesome, thanks! Posted a pull request at
>>> https://github.com/python/peps/pull/59 for ease of diff reading, and some
>>> commentary below (with aggressive snipping).
>>
>> Thanks - I'll do a proper review of that, but just wanted to make a
>> few comments here.
>
> Added some comments to the PR. Basically:
>
> 1. We could do with a better descrition of use cases.
> 2. We either require registry keys to be user-friendly (no UUIDs!) or
> we find an alternative approach for the virtualenv-style use case.
> 3. Registering "how to start the interpreter" (python.exe or whatever)
> should be mandatory.
>
> I don't think we're far off, though.

For what it's worth, the following code seems to do a reasonable job
of scanning the registry according to the rules in the PEP. If anyone
has access to any 3rd party installations of Python that follow the
proposed PEP's rules, it would be interesting to try this script
against them.

import winreg

def list_subkeys(key):
i = 0
while True:
try:
yield winreg.EnumKey(key, i)
except WindowsError:
return
i += 1

locations = [
("64-bit", winreg.HKEY_LOCAL_MACHINE, winreg.KEY_WOW64_64KEY),
("32-bit", winreg.HKEY_LOCAL_MACHINE, winreg.KEY_WOW64_32KEY),
("user",   winreg.HKEY_CURRENT_USER, 0),
]

if __name__ == "__main__":
seen = {}
for loc, hive, bits in locations:
k = winreg.CreateKeyEx(hive, "Software\\Python", 0,
winreg.KEY_READ | bits)
for company in list_subkeys(k):
sk = winreg.CreateKey(k, company)
for tag in list_subkeys(sk):
try:
prefix = winreg.QueryValue(sk, "{}\InstallPath".format(tag))
except WindowsError:
# If there's no InstallPath, it's not a valid registration
continue
clash = ""
if seen.get((company, tag)):
clash = "Overrides" if hive ==
winreg.HKEY_CURRENT_USER else "Ambiguous"
print("{}\{} ({}) {} {}".format(company, tag, loc,
prefix, clash))
seen[(company, tag)] = True

This code works (and gives the same results) on at least 2.7 and 3.4+
(32 and 64 bit). I didn't test on older versions. It was tricky enough
to get right that I'll probably package it up and publish it at some
point. Steve - if you want to add it to the PEP as a sample
implementation, that's fine with me, too.

Some notes:

1. Python 2.7 allows "Ambiguous" system installs. In other words, the
 is the same for 32 and 64 bit, but the installer doesn't stop
you installing both. Python 3.4 has the same  but the installer
prevents installing both 32 and 64 bit versions.
2. Prior to 3.5, it's impossible without running the interpreter or
inspecting the exe to determine if a user install is 32 or 64 bit. You
can tell for a system install based on which registry key you found
the data on.

As these are both legacy / "backward compatibility" issues, they
aren't a problem with the PEP as such.

Paul
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP487: Simpler customization of class creation

2016-07-19 Thread Nick Coghlan
On 19 July 2016 at 16:41, Neil Girdhar  wrote:
> Yes, I see what you're saying.   However, I don't understand why
> __init_subclass__ (defined on some class C) cannot be used to implement the
> checks required by @abstractmethod instead of doing it in ABCMeta.  This
> would prevent metaclass conflicts since you could use @abstractmethod with
> any metaclass or no metaclass at all provided you inherit from C.

ABCMeta also changes how __isinstance__ and __issubclass__ work and
adds additional methods (like register()), so enabling the use of
@abstractmethod without otherwise making the type an ABC would be very
confusing behaviour that we wouldn't enable by default.

But yes, this change does make it possible to write a mixin class that
implements the "@abstractmethod instances must all be overridden to
allow instances to to be created" logic from ABCMeta without otherwise
turning the class into an ABC instance.

Cheers,
Nick.

-- 
Nick Coghlan   |   [email protected]   |   Brisbane, Australia
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP487: Simpler customization of class creation

2016-07-19 Thread Neil Girdhar
Thanks for clarifying.

On Tue, Jul 19, 2016 at 10:34 AM Nick Coghlan  wrote:

> On 19 July 2016 at 16:41, Neil Girdhar  wrote:
> > Yes, I see what you're saying.   However, I don't understand why
> > __init_subclass__ (defined on some class C) cannot be used to implement
> the
> > checks required by @abstractmethod instead of doing it in ABCMeta.  This
> > would prevent metaclass conflicts since you could use @abstractmethod
> with
> > any metaclass or no metaclass at all provided you inherit from C.
>
> ABCMeta also changes how __isinstance__ and __issubclass__ work and
> adds additional methods (like register()), so enabling the use of
> @abstractmethod without otherwise making the type an ABC would be very
> confusing behaviour that we wouldn't enable by default.
>
> But yes, this change does make it possible to write a mixin class that
> implements the "@abstractmethod instances must all be overridden to
> allow instances to to be created" logic from ABCMeta without otherwise
> turning the class into an ABC instance.
>
> Cheers,
> Nick.
>
> --
> Nick Coghlan   |   [email protected]   |   Brisbane, Australia
>
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP487: Simpler customization of class creation

2016-07-19 Thread Sylvain Corlay
Hello,

This is my first post on python-dev and I hope that I am not breaking any
rule.

I wanted to react on the discussion regarding PEP487.

This year, we have been working on a refactoring of the `traitlets`
library, an implementation of the descriptor pattern that is used in
Project Jupyter / IPython. The motivations for the refactoring was similar
to those of this PEP: having a more generic metaclass allowing more
flexibility in terms of types of descriptors, in order to avoid conflicts
between meta classes.

We ended up with:
- A metaclass called MetaHasDescriptor
- A base class of meta MetaHasDescriptor named HasDescriptors

Usage:

class MyClass(HasDescriptors):
attr = DesType()

DesType inherits from a base Descriptor type. The key is that their
initialization is done in three stages

 - the main
DesType.__init__

 - the part of the initialization of DesType that depends on the definition
of MyClass
DesType.class_init(self, cls, name)
   which is called from MetaHasDescriptors.__new__

 - a method of DesType that depends on the definition of instances of
MyClass
DesType.instance_init(self, obj)
which is called from HasDescriptors.__new__.

instance_init, may make modifications on the HasDescriptors instance.

My understanding is that the proposed __set_name__ in PEP487 exactly
corresponds to our class_init, although interestingly we often do much more
in class_init than setting the name of the descriptor, such as setting a
this_class attribute or calling class_init on contained descriptors.
Therefore I do not think that the names __set_name__ or __set_owner__ are
appropriate for this use case.

In a way, the long-form explicit names for our class_init and instance_init
methods would be something like __init_fom_owner_class__, and
__touch_instance__.

Thanks,

Sylvain

PS: thanks to Neil Girdhar for the heads up on the traitlets repo.
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com