Есть ли модуль unicodedata для IronPython?

Я пытаюсь получить общий пример кода для службы selenium2 Sauce OnDemand, работающей с IronPython, для некоторой тестовой работы, которую я выполняю, и столкнулся с проблемой, которую не могу понять.

Во-первых, вот среда:

Windows 7 Домашняя расширенная, 64-разрядная версия.
IronPython 2.7.0.40 в .Net 4.0.30319.225

Мой путь:

>>> sys.path
['.', 'C:\\users\\me\\scripts\\python', 'C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\Common7\\IDE\\Extensions\\Microsoft\\IronStudio\\0.4\\Lib', 'C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\Common7\\IDE\\Extensions\\Microsoft\\IronStudio\\0.4\\DLLs', 'C:\\opt\\win\\ipy\\Lib', 'C:\\opt\\win\\ipy\\DLLs', 'C:\\opt\\win\\ipy']  

Я знаю, что у IronPython есть проблемы с использованием сжатых яиц, поэтому я извлек следующие библиотеки в каталог \Lib в sys.path:

селен (2.0b4dev)
rdflib (3.1.0)

Теперь пример кода от Sauce Labs:

import unittest
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

class Selenium2OnSauce(unittest.TestCase):

    def setUp(self):
        desired_capabilities = dict(platform="WINDOWS",
                                    browserName="firefox",
                                    version="3.6", 
                                    name="Hello, Selenium 2!")
        self.driver = webdriver.Remote(
            desired_capabilities=desired_capabilities,
            command_executor="http://me:[email protected]:80/wd/hub")

    def test_sauce(self):
        self.driver.get('http://example.saucelabs.com')
        assert "Sauce Labs" in self.driver.title

    def tearDown(self):
        self.driver.quit()

if __name__ == '__main__':
    unittest.main()

Вот ошибка, которую я получаю:

Traceback (most recent call last):
File "selenium2_test.py", line 3, in <module>
File "c:\opt\win\ipy\Lib\selenium\webdriver\__init__.py", line 18, in <module>
File "c:\opt\win\ipy\Lib\selenium\webdriver\firefox\webdriver.py", line 24, in <module>
File "c:\opt\win\ipy\Lib\selenium\webdriver\firefox\firefox_profile.py", line 23, in <module>
File "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\IronStudio\0.4\Lib\rdflib\__init__.py", line 65, in <module>
File "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft\IronStudio\0.4\Lib\rdflib\namespace.py", line 282, in <module>
ImportError: No module named unicodedata

Я пробовал искать пакеты с unicodedata в них (например, FePY), но ни один из них не работает. Я попытался скопировать .pyd из моей установки Python27, но это тоже не сработало.

Этого еще нет в IronPython 2.7? В качестве альтернативы, есть ли библиотека или пространство имен, на которые я могу ссылаться для выполнения той же задачи?

Если нет, думаю, мне придется обходиться без selenium2, пока ребята из Iron не получат unicodedata для IP27. :(

Спасибо,
Грег.


person Greg Gauthier    schedule 26.04.2011    source источник
comment
Итак, вы пытались использовать это? fepy. svn.sourceforge.net/viewvc/fepy/trunk/lib/ — вы сможете поместить его на путь Python. Какие ошибки возникают при попытке использовать версию FePY?   -  person Michael Greene    schedule 26.04.2011
comment
В одной версии я получал Невозможно импортировать категорию имен. С версией, которую вы связали, я получал Невозможно импортировать декомпозицию имени. Вероятно, нужно просто найти нужную версию этого модуля, но будь я проклят, если смогу ее найти. :/   -  person Greg Gauthier    schedule 26.04.2011
comment
Я могу ошибаться, и SO не обязательно подходит для такого рода вещей, но декомпозиция выглядит как нормализация для формы D, поэтому вы, вероятно, могли бы добавить к ссылке, которую я вам дал, def normalize(unichr): return String.Normalize(unichr.ToString(), NormalizationForm.FormD)   -  person Michael Greene    schedule 26.04.2011
comment
@Micheal: Спасибо за помощь! Это сработало, но я определил это как декомпозицию (а не нормализацию()). Почему все это не является частью обычной сборки IronPython? я не понимаю :/   -  person Greg Gauthier    schedule 26.04.2011
comment
Ironpython поддерживал юникод через .NET с самого начала. Следовательно, некоторые дополнительные модули не имели приоритета, поскольку существовали обходные пути. Это активная ошибка для IronPython, предназначенная для версии 2.7. выпускать. Реализация Unicodedata на Cpython — это pyd DLL. Возможно, вы сможете заставить его работать с помощью ironclad, но решение Майкла Грина лучше и, вероятно, ближе всего к тому, что реализуют разработчики IronPython.   -  person WombatPM    schedule 26.04.2011
comment
@Greg: конечно, это должно было быть определено как разложение, глупый я. Рад, что помог.   -  person Michael Greene    schedule 27.04.2011


Ответы (2)


Увы, модуль unicodedata на данный момент не включен в IronPython. Но не бойтесь! В грядущем релизе 2.7.1 он будет, и всех ваших проблем больше не будет.

Извини за это. Когда выйдет 2.7.1, думаю, в начале июня. Вы можете проверить https://github.com/IronLanguages/main/commit/5395af28b5794b0acf982ab87d174616925ab8 патч, но он довольно большой и неудобный из-за включенной базы данных Unicode.

person Jeff Hardy    schedule 26.04.2011
comment
Спасибо за новость, Джефф. Я ценю ваши усилия, несмотря на мои разочарования :) - person Greg Gauthier; 26.04.2011

См. комментарии @Micheal Greene к исходному вопросу. Вот модуль с правками, как указано:

# Copyright (c) 2006 by Seo Sanghyeon
# 2006-07-13 sanxiyn Created
# 2006-07-19 sanxiyn Added unidata_version, normalize
# Modified 2011 - Greg Gauthier - To provide needed functionality for rdflib
#                                 and other utilities, in IronPython 2.7.0

unidata_version = '3.2.0'

# --------------------------------------------------------------------
# Normalization

from System import String
from System.Text import NormalizationForm

def normalize(form, string):
    return String.Normalize(string, _form_mapping[form])

_form_mapping = {
    'NFC': NormalizationForm.FormC,
    'NFKC': NormalizationForm.FormKC,
    'NFD': NormalizationForm.FormD,
    'NFKD': NormalizationForm.FormKD,
}

# --------------------------------------------------------------------
# Character properties

from System.Globalization import CharUnicodeInfo

def _handle_default(function):
    def wrapper(unichr, default=None):
        result = function(unichr)
        if result != -1:
            return result
        if default is None:
            raise ValueError()
        return default
    return wrapper

decimal = _handle_default(CharUnicodeInfo.GetDecimalDigitValue)
digit = _handle_default(CharUnicodeInfo.GetDigitValue)
numeric = _handle_default(CharUnicodeInfo.GetNumericValue)

def category(unichr):
    uc = CharUnicodeInfo.GetUnicodeCategory(unichr)
    return _category_mapping[int(uc)]

_category_mapping = {
    0: 'Lu',
    1: 'Ll',
    2: 'Lt',
    3: 'Lm',
    4: 'Lo',
    5: 'Mn',
    6: 'Mc',
    7: 'Me',
    8: 'Nd',
    9: 'Nl',
    10: 'No',
    11: 'Zs',
    12: 'Zl',
    13: 'Zp',
    14: 'Cc',
    15: 'Cf',
    16: 'Cs',
    17: 'Co',
    18: 'Pc',
    19: 'Pd',
    20: 'Ps',
    21: 'Pe',
    22: 'Pi',
    23: 'Pf',
    24: 'Po',
    25: 'Sm',
    26: 'Sc',
    27: 'Sk',
    28: 'So',
    29: 'Cn',
}

# added for rdflib/ironpython
def decomposition(unichr): 
    return String.Normalize(unichr.ToString(), NormalizationForm.FormD)
person Greg Gauthier    schedule 26.04.2011