Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python3: incompatible metaclass syntax #8652

Closed
larry801 opened this Issue Aug 20, 2018 · 5 comments

Comments

4 participants
@larry801
Copy link

commented Aug 20, 2018

Metaclass is used in several places in NVDA code. Python3 changed the syntax of using a metaclass and it is not compatible with python 2.

Py2: syntax
metaclass = xxx
Py3 syntax
class A(metalcass=xxx):

We need "six" module to make metaclass run in Python2 and 3.
There are two tools in that module.
Which one is more suitable?

six.with_metaclass(metaclass, *bases)
or
@six.add_metaclass(metaclass)

@leonardder

This comment has been minimized.

Copy link
Collaborator

commented Aug 20, 2018

@six.add_metaclass looks way cleaner to me. See also this thread on stack overflow.

@leonardder

This comment has been minimized.

Copy link
Collaborator

commented Aug 21, 2018

@leonardder

This comment has been minimized.

Copy link
Collaborator

commented Aug 21, 2018

Thinking about this, I propose fixing this as part of #8393.

@leonardder leonardder added the Python 3 label Aug 21, 2018

@leonardder

This comment has been minimized.

Copy link
Collaborator

commented Aug 21, 2018

@six.add_metaclass fails for NVDAObject:

log snippet
CRITICAL - __main__ (15:19:51.082):
core failure
Traceback (most recent call last):
  File "nvda.pyw", line 214, in 
    core.main()
  File "core.py", line 223, in main
    import appModuleHandler
  File "appModuleHandler.py", line 27, in 
    import NVDAHelper
  File "NVDAHelper.py", line 19, in 
    import eventHandler
  File "eventHandler.py", line 9, in 
    import api
  File "api.py", line 11, in 
    import review
  File "review.py", line 10, in 
    from NVDAObjects import NVDAObject, NVDAObjectTextInfo
  File "NVDAObjects\__init__.py", line 146, in 
    class NVDAObject(documentBase.TextContainerObject,baseObject.ScriptableObject):
  File "d:\development\nvda\source repo\include\wxPython\six.py", line 847, in wrapper
    return metaclass(cls.__name__, cls.__bases__, orig_vars)
  File "baseObject.py", line 72, in __init__
    raise TypeError("%s is already a class attribute, cannot create descriptor with methods %s"%(x,methodsString))
TypeError: columnCount is already a class attribute, cannot create descriptor with methods 

with_metaclass works ok.

@josephsl

This comment has been minimized.

Copy link
Collaborator

commented Sep 3, 2018

Hi,

Update: my experiment shows that Python 3 approach is way superior, and with that, we don't have to worry about which six.meta* function to use. Besides, using native method looks way cleaner and also allows getters and setters to work properly by adding metaclass declaration when declaring classes. However, because we want to provide easy means of transition, I propose that #8393 be the venue for tackling this also, and come back to this once transition is taking place (leaving this open for now).

Thanks.

@leonardder leonardder added this to To do in Update NVDA to Python 3 via automation Dec 11, 2018

Update NVDA to Python 3 automation moved this from To do to Done Dec 13, 2018

@nvaccessAuto nvaccessAuto added this to the 2018.4 milestone Dec 13, 2018

feerrenrut added a commit that referenced this issue Dec 13, 2018

AutoPropertyObject: support abstract and class properties (PR #8393)
Closes #8294
Fixes #8652
Closes #8658

Properties and methods within classes can now be marked as abstract in NVDA. These classes will raise an error if instantiated.
See PR #8393 for full description.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.