python
Folders and files
| Name | Name | Last commit date | ||
|---|---|---|---|---|
parent directory.. | ||||
phonenumbers Python Library This is a Python port of libphonenumber, originally from: http://code.google.com/p/libphonenumber/. Original Java code is Copyright (C) 2009-2012 The Libphonenumber Authors =========================== phonenumbers Installation =========================== Install using setup.py: $ tar xfz phonenumbers-<version>.tar.gz $ cd phonenumbers-<version> $ python setup.py build $ sudo python setup.py install # or su first =========================== Running Tests =========================== With phonenumbers on the Python path, run: $ python -m testwrapper =========================== Auto-Generating Python Code =========================== The code within the python/phonenumbers/data subdirectory is automatically generated from the master XML metadata file (resources/PhoneNumberMetadata.xml). Similarly, the code in the python/phonenumbers/geodata subdirectory is automatically generated from the files in resources/geocoding/ The script tools/buildmetadatafromxml.py performs the first autogeneration. Run it with: cd tools python buildmetadatafromxml.py ../resources/PhoneNumberMetadata.xml ../python/phonenumbers/data . This will: - Create the python/phonenumbers/data/ directory if not present. - Create a collection of files, one for each region code: python/phonenumbers/data/region_<code>.py Each file contains the Python constructors for the metadata for that region. - Create a file python/phonenumbers/data/__init__.py which accumulates all of the per-region files. The script tools/buildgeocodingdata.py performs the second autogeneration. cd tools python buildgeocodingdata.py ../resources/geocoding ../python/phonenumbers/geodata/__init__.py This approach results in a large set of Python files, but makes it easy to apply local fixes to the formatting metadata. =========================== Library Developer Internals =========================== The Python code is derived from the original Java code, and mostly sticks to the structure of that code to make it easier to include future changes to the upstream code. However, there are a number of differences: - Naming conventions are converted to Python standards; in particular, method names are connected_with_underscores rather than beingInCamelCase. - The PhoneNumber and PhoneMetadata classes are written by hand based on the Java code and the protocol buffer definitions, rather than by using the the Python protocol buffer library. This makes the mapping to the Java code easier to follow, and allows for the custom modifications that have been made to the base protocol buffer. Attribute values of None are used to indicate that a particular (optional) attribute is not present (instead of hasAttribute() methods). - The Java PhoneNumberUtil class was a singleton, and so its contents are included at the top level in phonenumberutil.py. Static methods from the PhoneNumberUtil class thus become functions in phonenumberutil.py; private and package methods get a leading underscore in their name. - Accessor functions (setAttribute() and getAttribute() are avoided, and direct access to attributes is used instead. - Methods named get_something_from(object) are typically renamed to something_from(object). - The format() methods in PhoneNumberUtil were renamed to format_number() to avoid clashing with the Python built-in format(). - The internals of phonenumberutil.py do not have logging. - The Python version is less concerned with speed and size optimization than the Java version (as Python code is more likely to run on a server platform, and less likely to run on an embedded/smartphone platform). Much of the functionality of this library depends on regular expressions, so it's worth highlighting the translation between Java and Python regexps: - Java replacement group references are "$1 $2" etc, Python's are "\1 \2" etc. - Java Matcher(x).lookingAt() translates to Python re_obj.match(x) - Java Matcher(x).find() translates to Python m = re.search(x). - Java Matcher(x).matches() translates to Python m = re_obj.match(x) together with a check that m.end() == len(x). The last of these is encapsulated in the fullmatch() function in re_util.py. =========================== Release Procedure =========================== Standard Python v2.x version: - Ensure that python/HISTORY file is up-to-date. - Set the __version__ field in python/phonenumbers/__init__.py - Check that the list of symbols in python/phonenumbers/__init__.py __all__ is up to date. The tools/python/allcheck.py script helps with this. - Check that the unit tests all run successfully: cd tools/python && make test - Check that Python 2.5 is still supported: cd tools/python && make PYTHON=python2.5 test - Create a release-<version> branch and shift to it with: git checkout -b release-<version> - Push the branch to Github with: git push <github-remote> release-<version> - Push the package to PyPI with: cd python && setup.py sdist upload Experimental Python v3.x version: - Perform the v2.x release procedure above. - Build the python3/ code and test it with: cd tools/python && make test3 - Create a py3k-release-<version> branch and shift to it with: git checkout -b py3k-release-<version> - Push the branch to Github with: git push origin py3k-release-<version> - Create a setup-tools packaged tarball dist/phonenumbers3k-<version>.tar.gz with: cd python3 && make sdist # runs python3 setup.py sdist