Welcome, guest | Sign In | My Account | Store | Cart

Notice! PyPM is being replaced with the ActiveState Platform, which enhances PyPM’s build and deploy capabilities. Create your free Platform account to download ActivePython or customize Python with the packages you require and get automatic updates.

pypm install gocept.country

How to install gocept.country

  1. Download and install ActivePython
  2. Open Command Prompt
  3. Type pypm install gocept.country
 Python 2.7Python 3.2Python 3.3
Windows (32-bit)
0.6.4 Available View build log
Windows (64-bit)
0.6.4 Available View build log
Mac OS X (10.5+)
0.6.4 Available View build log
Linux (32-bit)
0.6.4 Available View build log
Linux (64-bit)
0.6.4 Available View build log
ZPL 2.1
Depended by
Lastest release
version 0.6.4 on Jan 5th, 2011

This package lets you use the pycountry database within Zope 3.

In practice, this means e.g., that you can easily get a zope.schema.Choice field to provide a full list of iso 3166 country codes.

For more information about the database please refer to the pycountry product.


gocept.country provides Zope 3 sources for the pycountry databases. You can use it e.g. to get a zope.schema.Choice field with all iso 3166 countries.

>>> import gocept.country
>>> import gocept.country.db
>>> import zope.schema
ISO 3166 Countries

To get a list of ISO 3166 countries in a webform, you can use the zope.schema.Choice field and provide the gocept.country.countries as source:

>>> countries_field = zope.schema.Choice(title=u'Country',
...                            source=gocept.country.countries)
>>> countries_field
<zope.schema._field.Choice object at 0x...>
>>> countries = iter(countries_field.source)

The gocept.country.countries sourcefactory returns Country objects as values, which use the values from pycountry:

>>> afghanistan = countries.next()
>>> afghanistan
<gocept.country.db.Country object at 0x...>
>>> afghanistan.name

Calling the next() method again returns the next country from the source:

>>> islands = countries.next()
>>> islands.name
u'\xc5land Islands'

There are all information available, which you can get from pycountry:

>>> afghanistan.alpha2
>>> afghanistan.alpha3
>>> afghanistan.numeric
>>> afghanistan.official_name
'Islamic Republic of Afghanistan'

To smaller the amount of results you can provide a list or tuple of countries you like to have in your source:

>>> countries = iter(gocept.country.CountrySource(alpha2=['DE', 'US']))
>>> countries.next().name
>>> countries.next().name
u'United States'
>>> countries.next().name
Traceback (most recent call last):

Please note, that the result items are sorted by alpha2 code. Please also note, that you can provide alpha3 and numeric codes and names resp. official_names to smaller the amount of result items, too:

>>> len(list(gocept.country.CountrySource()))
>>> len(list(gocept.country.CountrySource(alpha2=['DE', 'US', 'GB'])))
>>> len(list(gocept.country.CountrySource(alpha3=['DEU', 'USA'])))
>>> len(list(gocept.country.CountrySource(numeric=['276', ])))
>>> countries_list = ['Germany', 'Italy', 'Poland', 'France']
>>> len(list(gocept.country.CountrySource(name=countries_list)))

Providing codes, which are not present, does not results in an exception but in an empty list:

>>> len(list(gocept.country.CountrySource(capital=['Berlin', 'Paris'])))
ISO 3166-2 Country subdivisions
Contextless source

Country subdivisions are similar to countries:

>>> subdivisions_field = zope.schema.Choice(
...     title=u'Country subdivisions', source=gocept.country.subdivisions)
>>> subdivisions = iter(subdivisions_field.source)
>>> la_vella = subdivisions.next()
>>> la_vella.name
u'Andorra la Vella'
>>> la_vella.code
>>> canillo = subdivisions.next()
>>> canillo.name
>>> canillo.code

Please note, that the result items are sorted by their code. Please also note, that you can provide names and numeric codes to smaller the amount of result items, too.

>>> len(list(gocept.country.SubdivisionSource()))
>>> len(list(gocept.country.SubdivisionSource(code=['DE-ST', 'US-WA'])))
>>> len(list(gocept.country.SubdivisionSource(country_code=['DE'])))
>>> [x.name
...  for x in gocept.country.SubdivisionSource(country_code=['DE'])][1:3]
[u'Bayern', u'Bremen']
>>> len(list(gocept.country.SubdivisionSource(
...     name=[u'Bayern', u'Bremen'])))
Contextual source

There is also a contextual source for country subdivisions which depends on a country. Let's set up a context object first:

>>> import zope.interface
>>> class IAddress(zope.interface.Interface):
...     country = zope.interface.Attribute("The country of the address.")
...     subdivision = zope.schema.Choice(
...         title=u'Country subdivisions',
...         source=gocept.country.contextual_subdivisions)
>>> class Address(object):
...     zope.interface.implements(IAddress)
>>> address = Address()
>>> address.country = gocept.country.db.Country('DE')

The contextual source expects an adapter between the context and gocept.country.interfaces.ICountry:

>>> import zope.component
>>> import gocept.country.interfaces
>>> def get_country(context):
...     return context.country
>>> zope.component.provideAdapter(
...    get_country, (IAddress, ), gocept.country.interfaces.ICountry)
>>> gocept.country.interfaces.ICountry(address).name

So the source contains only the country subdivisions belonging to the country:

>>> len(list(iter(gocept.country.contextual_subdivisions(address))))
>>> [x.name
...  for x in iter(gocept.country.contextual_subdivisions(address))][1:3]
[u'Bayern', u'Bremen']

Changing the country changes also the subdivisions:

>>> address.country = gocept.country.db.Country('CH')
>>> len(list(iter(gocept.country.contextual_subdivisions(address))))
>>> [x.name
...  for x in iter(gocept.country.contextual_subdivisions(address))]
[u'Aargau', u'Appenzell Innerrhoden', ...]
>>> [x.code
...  for x in iter(gocept.country.contextual_subdivisions(address))]
['CH-AG', 'CH-AI', ...]
>>> gocept.country.contextual_subdivisions.factory.getTitle(
...     address, gocept.country.db.Subdivision('CH-AG'))

If the country is not set leads to no subdivisions:

>>> address.country = None
>>> len(list(iter(gocept.country.contextual_subdivisions(address))))
>>> list(iter(gocept.country.contextual_subdivisions(address)))
ISO 15924 Scripts

Scripts are similar to countries:

>>> scripts_field = zope.schema.Choice(title=u'Script',
...                            source=gocept.country.scripts)
>>> scripts = iter(scripts_field.source)
>>> arabic = scripts.next()
>>> arabic.name
>>> aramaic = scripts.next()
>>> aramaic.name
u'Imperial Aramaic'

Please note, that the result items are sorted by alpha4 code. Please also note, that you can provide names and numeric codes to smaller the amount of result items, too.

>>> len(list(gocept.country.ScriptSource()))
>>> len(list(gocept.country.ScriptSource(alpha4=['Arab', 'Latn'])))
>>> len(list(gocept.country.ScriptSource(numeric=['215', ])))
>>> len(list(gocept.country.ScriptSource(name=['Arabic', 'Latin'])))
ISO 4217 Currencies

Currencies are, again, similar to the ones before:

>>> currencies_field = zope.schema.Choice(title=u'Currency',
...                            source=gocept.country.currencies)
>>> currencies = iter(currencies_field.source)
>>> dirham = currencies.next()
>>> dirham.name
u'UAE Dirham'
>>> afghani = currencies.next()
>>> afghani.name

Please note, that the result items are sorted by letter code. Please also note, that you can provide names and numeric codes to smaller the amount of result items, too.

>>> len(list(gocept.country.CurrencySource()))
>>> len(list(gocept.country.CurrencySource(letter=['ARS', 'AED', 'AFN'])))
>>> len(list(gocept.country.CurrencySource(numeric=['032', '784'])))
>>> len(list(gocept.country.CurrencySource(name=['Afghani', ])))
ISO 639 Languages

Languages are similar, too:

>>> languages_field = zope.schema.Choice(title=u'Language',
...                            source=gocept.country.languages)
>>> languages = iter(languages_field.source)
>>> afar = languages.next()
>>> afar.name
>>> abkhazian = languages.next()
>>> abkhazian.name

Please note, that the result items are sorted by bibliographic. Please also note, that you can provide alpha2 and terminology codes and names to smaller the amount of result items, too.

>>> len(list(gocept.country.LanguageSource()))
>>> len(list(gocept.country.LanguageSource(alpha2=['an', 'en', 'de'])))
>>> len(list(gocept.country.LanguageSource(bibliographic=['eng', 'ger'])))
>>> len(list(gocept.country.LanguageSource(terminology=['arg', 'abk'])))
>>> len(list(gocept.country.LanguageSource(name=['English', 'German'])))

First we fetch a specific country:

>>> countries = list(iter(countries_field.source))
>>> germany = countries[80]
>>> germany.name

The i18n translate method translates 'Germany' into german:

>>> zope.i18n.translate(germany.name, target_language='de')

Translations are also operating for scripts, currencies and languages.


Countries, scripts, currenties and languages can be compared to equality. To test this, we will need another country object afghanistan, which is not the same object as retrieved before:

>>> countries = iter(countries_field.source)
>>> afghanistan = countries.next()
>>> countries = iter(countries_field.source)
>>> afghanistan2 = countries.next()
>>> str(afghanistan) == str(afghanistan2)

Comparing them will get the token for each and compare it:

>>> afghanistan == afghanistan2
>>> afghanistan != afghanistan2
>>> afghanistan != germany
>>> afghanistan == germany

Comparing with an instance of another class always returns False:

>>> afghanistan == None
>>> afghanistan == object()
Pickling and unpickling

It should be possible to store "proxy objects" in a database (like the ZODB). Therefore, they have to be pickleable:

>>> import StringIO
>>> import cPickle
>>> f = StringIO.StringIO('')
>>> f.read()

Pickling a country should never raise an error...

>>> cPickle.dump(afghanistan, f)

... and results in storing the token in the pickle:

>>> f.seek(0)
>>> 'AF' in f.read()

Reading the pickle again will return the same country which was pickled before:

>>> f.seek(0)
>>> afghanistan2 = cPickle.load(f)
>>> afghanistan2 == afghanistan
>>> afghanistan2.name
0.6.4 (2008-10-21)
  • Bugfix: declared namespace package in setup.py
0.6.3 (2008-10-14)
  • Bugfix: added not-equal compare method for db objects
0.6.2 (2008-10-13)
  • Added security declarations for token.
  • Bugfix in comparison of db objects, where isinstance returns False

System Message: WARNING/2 (<string>, line 425)

Bullet list ends without a blank line; unexpected unindent.

for objects of the same type

0.6.1 (2008-09-13)
  • Bugfix in countextual subdivision source: parameters of some methods

System Message: WARNING/2 (<string>, line 431)

Bullet list ends without a blank line; unexpected unindent.

where in wrong order.

0.6 (2008-09-12)
  • Added contextual country subdivision source, so country subdivisions

System Message: WARNING/2 (<string>, line 437)

Bullet list ends without a blank line; unexpected unindent.

can depend on the country.

0.5 (2008-09-11)
  • Added support for country subdivisions.
0.4.2 (2008-09-10)
  • Added security declarations for tokens.
0.4.1 (2008-09-10)
  • Fixed bug in token comparison.
0.4 (2008-06-10)
  • added possibility to smaller the amount of results generated by the

System Message: WARNING/2 (<string>, line 459)

Bullet list ends without a blank line; unexpected unindent.


0.3 (2008-05-21)
  • added test for comparing the returned countries to equality
  • added __reduce__ to data objects so that they can be pickled
  • added tests for pickling and unpickling data objects
0.2 (2008-05-20)
  • gocept.country now returns special data objects instead of pycountry

System Message: WARNING/2 (<string>, line 474)

Bullet list ends without a blank line; unexpected unindent.

objects for a better object-oriented purpose and flexibility in handling the result - improved configure.zcml and added functional tests for the i18n translations - improved test cases in general

0.1 (2008-05-20)
  • initial release
  • Michael Howitz <mh at gocept dot com>

Subscribe to package updates

Last updated Jan 5th, 2011

Download Stats

Last month:1

What does the lock icon mean?

Builds marked with a lock icon are only available via PyPM to users with a current ActivePython Business Edition subscription.

Need custom builds or support?

ActivePython Enterprise Edition guarantees priority access to technical support, indemnification, expert consulting and quality-assured language builds.

Plan on re-distributing ActivePython?

Get re-distribution rights and eliminate legal risks with ActivePython OEM Edition.