Imported Upstream version 3.27.1 upstream/3.27.1
authorDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 30 Oct 2018 01:29:47 +0000 (10:29 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Tue, 30 Oct 2018 01:29:47 +0000 (10:29 +0900)
56 files changed:
ChangeLog
INSTALL [deleted file]
MANIFEST.in
Makefile.am
Makefile.in
NEWS
PKG-INFO
PKG-INFO.in
README.rst
configure
configure.ac
docs/Makefile [new file with mode: 0644]
docs/changelog.rst [new file with mode: 0644]
docs/conf.py [new file with mode: 0644]
docs/contact.rst [new file with mode: 0644]
docs/devguide/building_testing.rst [new file with mode: 0644]
docs/devguide/dev_environ.rst [new file with mode: 0644]
docs/devguide/index.rst [new file with mode: 0644]
docs/devguide/override_guidelines.rst [new file with mode: 0644]
docs/devguide/overview.rst [new file with mode: 0644]
docs/devguide/style_guide.rst [new file with mode: 0644]
docs/extra.css [new file with mode: 0644]
docs/further.rst [new file with mode: 0644]
docs/getting_started.rst [new file with mode: 0644]
docs/guide/api/api.rst [new file with mode: 0644]
docs/guide/api/basic_types.rst [new file with mode: 0644]
docs/guide/api/flags_enums.rst [new file with mode: 0644]
docs/guide/api/gobject.rst [new file with mode: 0644]
docs/guide/api/index.rst [new file with mode: 0644]
docs/guide/api/properties.rst [new file with mode: 0644]
docs/guide/api/signals.rst [new file with mode: 0644]
docs/guide/cairo_integration.rst [new file with mode: 0644]
docs/guide/code/cairo-demo.py [new file with mode: 0755]
docs/guide/debug_profile.rst [new file with mode: 0644]
docs/guide/deploy.rst [new file with mode: 0644]
docs/guide/faq.rst [new file with mode: 0644]
docs/guide/images/cairo_integration.png [new file with mode: 0644]
docs/guide/index.rst [new file with mode: 0644]
docs/guide/porting.rst [new file with mode: 0644]
docs/guide/testing.rst [new file with mode: 0644]
docs/guide/threading.rst [new file with mode: 0644]
docs/icons.rst [new file with mode: 0644]
docs/images/LICENSE [new file with mode: 0644]
docs/images/favicon.ico [new file with mode: 0644]
docs/images/logo.svg [new file with mode: 0644]
docs/images/overview.dia [new file with mode: 0644]
docs/images/overview.svg [new file with mode: 0644]
docs/images/pygobject-small.svg [new file with mode: 0644]
docs/images/pygobject.svg [new file with mode: 0644]
docs/images/start_linux.png [new file with mode: 0644]
docs/images/start_macos.png [new file with mode: 0644]
docs/images/start_windows.png [new file with mode: 0644]
docs/index.rst [new file with mode: 0644]
docs/maintguide.rst [new file with mode: 0644]
docs/packagingguide.rst [new file with mode: 0644]
setup.py

index c302ac3..1604c01 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,216 @@
+commit 2e30c7fbfcb579efb2ff7134979f169f673ac285
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date:   Mon Dec 11 18:32:16 2017 +0100
+
+    Revert "setup.py: Also set setup_requires to require pycairo"
+
+    This reverts commit bab1cb0d98e4a6219332394161dbf07aafa0c615.
+
+    pycairo gets installed under /tmp as an .egg this way, and that
+    doesn't help us
+    with finding the C headers.
+
+ setup.py | 4 ----
+ 1 file changed, 4 deletions(-)
+
+commit bab1cb0d98e4a6219332394161dbf07aafa0c615
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date:   Mon Dec 11 16:26:54 2017 +0100
+
+    setup.py: Also set setup_requires to require pycairo
+
+    We need pycairo at build time. There are some problems with
+    setup_requires
+    in that it isn't directly handled by pip, but let's give it a try
+    and see
+    which problems come up.
+
+    Thanks to mgedmin for pointing that out
+
+ setup.py | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+commit 47aeaab6142a716234e91e8bbc3adefeff9ff5c3
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date:   Mon Dec 11 16:14:34 2017 +0100
+
+    setup.py: Provide a os.path.samefile fallback for Python 2 under
+    Windows
+
+    os.path.samefile is missing from Python 2 under Windows. Implement a
+    simple fallback which normalizes and compares paths instead.
+
+ setup.py | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+commit dfab41d0b66a15c8cf8229f7522160ec6b08a2b8
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date:   Sun Dec 10 20:38:47 2017 +0100
+
+    Add sphinx based documentation
+
+    Takes the documentation developed at
+    https://github.com/pygobject/pygobject-docs
+    and puts into /docs
+
+    See https://pygobject.readthedocs.io for how it looks
+
+    Now that we move to gitlab we can use webhooks to trigger builds
+    on readthedocs from gitlab directly and we should also have a nicer
+    contribution UX.
+
+    This also gets rid of most of README/HACKING/INSTALL and moves most
+    of the information into the documentation. The README is kept short
+    and only makes clear what pygobject is and points to the online docs
+    as that should answer all questions.
+
+    setup.py now sets the content of README.rst as long_descriptions,
+    as that is the content shown on PyPI. This makes the page on PyPI
+    look the same as on gitlab.
+
+    https://bugzilla.gnome.org/show_bug.cgi?id=791448
+
+ .gitignore                              |   2 +
+ HACKING                                 |  37 ----
+ INSTALL                                 | 370
+ --------------------------------
+ MANIFEST.in                             |   3 +-
+ Makefile.am                             |   5 +-
+ README.rst                              | 137 ++----------
+ docs/Makefile                           |  16 ++
+ docs/changelog.rst                      |  10 +
+ docs/conf.py                            |  50 +++++
+ docs/contact.rst                        |  11 +
+ docs/devguide/building_testing.rst      |  56 +++++
+ docs/devguide/dev_environ.rst           |  46 ++++
+ docs/devguide/index.rst                 |  13 ++
+ docs/devguide/override_guidelines.rst   |  90 ++++++++
+ docs/devguide/overview.rst              |  32 +++
+ docs/devguide/style_guide.rst           | 101 +++++++++
+ docs/extra.css                          |  57 +++++
+ docs/further.rst                        |  10 +
+ docs/getting_started.rst                | 128 +++++++++++
+ docs/guide/api/api.rst                  |  75 +++++++
+ docs/guide/api/basic_types.rst          |  53 +++++
+ docs/guide/api/flags_enums.rst          |  39 ++++
+ docs/guide/api/gobject.rst              |  91 ++++++++
+ docs/guide/api/index.rst                |  12 ++
+ docs/guide/api/properties.rst           | 119 ++++++++++
+ docs/guide/api/signals.rst              |  93 ++++++++
+ docs/guide/cairo_integration.rst        |  39 ++++
+ docs/guide/code/cairo-demo.py           | 133 ++++++++++++
+ docs/guide/debug_profile.rst            | 112 ++++++++++
+ docs/guide/deploy.rst                   |  52 +++++
+ docs/guide/faq.rst                      |  11 +
+ docs/guide/images/cairo_integration.png | Bin 0 -> 24418 bytes
+ docs/guide/index.rst                    |  17 ++
+ docs/guide/porting.rst                  | 109 ++++++++++
+ docs/guide/testing.rst                  |  39 ++++
+ docs/guide/threading.rst                | 290 +++++++++++++++++++++++++
+ docs/icons.rst                          |  48 +++++
+ docs/images/LICENSE                     |   3 +
+ docs/images/favicon.ico                 | Bin 0 -> 34494 bytes
+ docs/images/logo.svg                    | 266 +++++++++++++++++++++++
+ docs/images/overview.dia                | Bin 0 -> 1885 bytes
+ docs/images/overview.svg                |  72 +++++++
+ docs/images/pygobject-small.svg         | 193 +++++++++++++++++
+ docs/images/pygobject.svg               | 244 +++++++++++++++++++++
+ docs/images/start_linux.png             | Bin 0 -> 9893 bytes
+ docs/images/start_macos.png             | Bin 0 -> 13949 bytes
+ docs/images/start_windows.png           | Bin 0 -> 11454 bytes
+ docs/index.rst                          |  89 ++++++++
+ docs/maintguide.rst                     |  32 +++
+ docs/packagingguide.rst                 |  55 +++++
+ setup.py                                |   6 +-
+ 51 files changed, 2933 insertions(+), 533 deletions(-)
+
+commit 307e64982fdfcc9b505d867c0628e1e0a189cd67
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date:   Sun Dec 10 16:23:45 2017 +0100
+
+    PKG-INFO: Revert name back to PyGObject
+
+    My thinking there was that it gives us the same naming of tarballs
+    as with the autotools build system. But on a second thought, we
+    can't use the same tarball anyway due to gz vs xz and while the
+    naming should be case insensitive it's not worth the risk.
+
+    The commit changing it was 3e455944f5835c7509
+
+ PKG-INFO.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit eb20f3c9f062fe25a44068ccab46475c4cb5e523
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date:   Sun Dec 10 16:17:28 2017 +0100
+
+    setup.py: Rework pycairo discovery to not use pkg-config
+
+    Two problems with the previous approach:
+
+    * We looked into sys.prefix for the .pc file while the package
+      could be installed in another location like the user dir location
+      or on Debian it goes into /usr/local.
+    * The .pc file intalled by pycairo can contain wrong paths if
+      installed through pip, since that sometimes builds a wheel
+      and caches that for future installations to different locations.
+
+    Instead of using the .pc file use pkg_resources to discover the
+    pycairo location and then try to find the correspinding "data"
+    installation
+    path for the first  matching location scheme.
+
+    See https://github.com/pygobject/pycairo/issues/85
+
+ setup.py | 44 +++++++++++++++++++++++++++-----------------
+ 1 file changed, 27 insertions(+), 17 deletions(-)
+
+commit de2ff6e883015741527638ab5cece47a97ef2856
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date:   Sat Dec 9 15:59:26 2017 +0100
+
+    setup.py: Fix the distcheck command on Windows
+
+    The distutils install command complains if the passed root/record
+    paths
+    aren't absolute on Windows.
+    Also make use of os.path.join() while at it.
+
+ setup.py | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+commit 46225bf34fc5737ca5b8e9fd9a0029e6f4a8b302
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date:   Sat Dec 9 15:55:39 2017 +0100
+
+    setup.py: Remove various classifiers and the download-url which
+    aren't accepted by pypi
+
+    pypi does not allow uploading packages with these set, so remove
+    them altogether.
+
+ PKG-INFO.in | 5 -----
+ setup.py    | 1 -
+ 2 files changed, 6 deletions(-)
+
+commit bf884345be38f1ebd53fbe891841348b8485dac0
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date:   Fri Dec 8 20:34:18 2017 +0100
+
+    version bump
+
+ configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+commit f8801c24993e9b7b9abc65e32d1a851c7ed09649
+Author: Christoph Reiter <creiter@src.gnome.org>
+Date:   Fri Dec 8 20:31:17 2017 +0100
+
+    release 3.27.0
+
+ NEWS | 34 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 34 insertions(+)
+
 commit eb2ff4362878d0e348c67c606a32e8d332e2454d
 Author: Christoph Reiter <creiter@src.gnome.org>
 Date:   Fri Dec 8 16:56:10 2017 +0100
diff --git a/INSTALL b/INSTALL
deleted file mode 100644 (file)
index d60e29a..0000000
--- a/INSTALL
+++ /dev/null
@@ -1,370 +0,0 @@
-Installation Instructions
-*************************
-
-Copyright (C) 1994-1996, 1999-2002, 2004-2012 Free Software Foundation,
-Inc.
-
-   Copying and distribution of this file, with or without modification,
-are permitted in any medium without royalty provided the copyright
-notice and this notice are preserved.  This file is offered as-is,
-without warranty of any kind.
-
-Basic Installation
-==================
-
-   Briefly, the shell commands './configure; make; make install' should
-configure, build, and install this package.  The following
-more-detailed instructions are generic; see the 'README' file for
-instructions specific to this package.  Some packages provide this
-'INSTALL' file but do not implement all of the features documented
-below.  The lack of an optional feature in a given package is not
-necessarily a bug.  More recommendations for GNU packages can be found
-in *note Makefile Conventions: (standards)Makefile Conventions.
-
-   The 'configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation.  It uses
-those values to create a 'Makefile' in each directory of the package.
-It may also create one or more '.h' files containing system-dependent
-definitions.  Finally, it creates a shell script 'config.status' that
-you can run in the future to recreate the current configuration, and a
-file 'config.log' containing compiler output (useful mainly for
-debugging 'configure').
-
-   It can also use an optional file (typically called 'config.cache'
-and enabled with '--cache-file=config.cache' or simply '-C') that saves
-the results of its tests to speed up reconfiguring.  Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.
-
-   If you need to do unusual things to compile the package, please try
-to figure out how 'configure' could check whether to do them, and mail
-diffs or instructions to the address given in the 'README' so they can
-be considered for the next release.  If you are using the cache, and at
-some point 'config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
-   The file 'configure.ac' (or 'configure.in') is used to create
-'configure' by a program called 'autoconf'.  You need 'configure.ac' if
-you want to change it or regenerate 'configure' using a newer version
-of 'autoconf'.
-
-   The simplest way to compile this package is:
-
-  1. 'cd' to the directory containing the package's source code and type
-     './configure' to configure the package for your system.
-
-     Running 'configure' might take a while.  While running, it prints
-     some messages telling which features it is checking for.
-
-  2. Type 'make' to compile the package.
-
-  3. Optionally, type 'make check' to run any self-tests that come with
-     the package, generally using the just-built uninstalled binaries.
-
-  4. Type 'make install' to install the programs and any data files and
-     documentation.  When installing into a prefix owned by root, it is
-     recommended that the package be configured and built as a regular
-     user, and only the 'make install' phase executed with root
-     privileges.
-
-  5. Optionally, type 'make installcheck' to repeat any self-tests, but
-     this time using the binaries in their final installed location.
-     This target does not install anything.  Running this target as a
-     regular user, particularly if the prior 'make install' required
-     root privileges, verifies that the installation completed
-     correctly.
-
-  6. You can remove the program binaries and object files from the
-     source code directory by typing 'make clean'.  To also remove the
-     files that 'configure' created (so you can compile the package for
-     a different kind of computer), type 'make distclean'.  There is
-     also a 'make maintainer-clean' target, but that is intended mainly
-     for the package's developers.  If you use it, you may have to get
-     all sorts of other programs in order to regenerate files that came
-     with the distribution.
-
-  7. Often, you can also type 'make uninstall' to remove the installed
-     files again.  In practice, not all packages have tested that
-     uninstallation works correctly, even though it is required by the
-     GNU Coding Standards.
-
-  8. Some packages, particularly those that use Automake, provide `make
-     distcheck', which can by used by developers to test that all other
-     targets like 'make install' and 'make uninstall' work correctly.
-     This target is generally not run by end users.
-
-Compilers and Options
-=====================
-
-   Some systems require unusual options for compilation or linking that
-the 'configure' script does not know about.  Run './configure --help'
-for details on some of the pertinent environment variables.
-
-   You can give 'configure' initial values for configuration parameters
-by setting variables in the command line or in the environment.  Here
-is an example:
-
-     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
-
-   *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
-   You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory.  To do this, you can use GNU 'make'.  'cd' to the
-directory where you want the object files and executables to go and run
-the 'configure' script.  'configure' automatically checks for the
-source code in the directory that 'configure' is in and in '..'.  This
-is known as a "VPATH" build.
-
-   With a non-GNU 'make', it is safer to compile the package for one
-architecture at a time in the source code directory.  After you have
-installed the package for one architecture, use 'make distclean' before
-reconfiguring for another architecture.
-
-   On MacOS X 10.5 and later systems, you can create libraries and
-executables that work on multiple system types--known as "fat" or
-"universal" binaries--by specifying multiple '-arch' options to the
-compiler but only a single '-arch' option to the preprocessor.  Like
-this:
-
-     ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
-                 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
-                 CPP="gcc -E" CXXCPP="g++ -E"
-
-   This is not guaranteed to produce working output in all cases, you
-may have to build one architecture at a time and combine the results
-using the 'lipo' tool if you have problems.
-
-Installation Names
-==================
-
-   By default, 'make install' installs the package's commands under
-'/usr/local/bin', include files under '/usr/local/include', etc.  You
-can specify an installation prefix other than '/usr/local' by giving
-'configure' the option '--prefix=PREFIX', where PREFIX must be an
-absolute file name.
-
-   You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files.  If you
-pass the option '--exec-prefix=PREFIX' to 'configure', the package uses
-PREFIX as the prefix for installing programs and libraries.
-Documentation and other data files still use the regular prefix.
-
-   In addition, if you use an unusual directory layout you can give
-options like '--bindir=DIR' to specify different values for particular
-kinds of files.  Run 'configure --help' for a list of the directories
-you can set and what kinds of files go in them.  In general, the
-default for these options is expressed in terms of '${prefix}', so that
-specifying just '--prefix' will affect all of the other directory
-specifications that were not explicitly provided.
-
-   The most portable way to affect installation locations is to pass the
-correct locations to 'configure'; however, many packages provide one or
-both of the following shortcuts of passing variable assignments to the
-'make install' command line to change installation locations without
-having to reconfigure or recompile.
-
-   The first method involves providing an override variable for each
-affected directory.  For example, `make install
-prefix=/alternate/directory' will choose an alternate location for all
-directory configuration variables that were expressed in terms of
-'${prefix}'.  Any directories that were specified during 'configure',
-but not in terms of '${prefix}', must each be overridden at install
-time for the entire installation to be relocated.  The approach of
-makefile variable overrides for each directory variable is required by
-the GNU Coding Standards, and ideally causes no recompilation.
-However, some platforms have known limitations with the semantics of
-shared libraries that end up requiring recompilation when using this
-method, particularly noticeable in packages that use GNU Libtool.
-
-   The second method involves providing the 'DESTDIR' variable.  For
-example, 'make install DESTDIR=/alternate/directory' will prepend
-'/alternate/directory' before all installation names.  The approach of
-'DESTDIR' overrides is not required by the GNU Coding Standards, and
-does not work on platforms that have drive letters.  On the other hand,
-it does better at avoiding recompilation issues, and works well even
-when some directory options were not specified in terms of '${prefix}'
-at 'configure' time.
-
-Optional Features
-=================
-
-   If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving 'configure' the
-option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'.
-
-   Some packages pay attention to '--enable-FEATURE' options to
-'configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to '--with-PACKAGE' options, where PACKAGE
-is something like 'gnu-as' or 'x' (for the X Window System).  The
-'README' should mention any '--enable-' and '--with-' options that the
-package recognizes.
-
-   For packages that use the X Window System, 'configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the 'configure' options '--x-includes=DIR' and
-'--x-libraries=DIR' to specify their locations.
-
-   Some packages offer the ability to configure how verbose the
-execution of 'make' will be.  For these packages, running `./configure
---enable-silent-rules' sets the default to minimal output, which can be
-overridden with 'make V=1'; while running `./configure
---disable-silent-rules' sets the default to verbose, which can be
-overridden with 'make V=0'.
-
-Particular systems
-==================
-
-   On HP-UX, the default C compiler is not ANSI C compatible.  If GNU
-CC is not installed, it is recommended to use the following options in
-order to use an ANSI C compiler:
-
-     ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
-
-and if that doesn't work, install pre-built binaries of GCC for HP-UX.
-
-   HP-UX 'make' updates targets which have the same time stamps as
-their prerequisites, which makes it generally unusable when shipped
-generated files such as 'configure' are involved.  Use GNU 'make'
-instead.
-
-   On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
-parse its '<wchar.h>' header file.  The option '-nodtk' can be used as
-a workaround.  If GNU CC is not installed, it is therefore recommended
-to try
-
-     ./configure CC="cc"
-
-and if that doesn't work, try
-
-     ./configure CC="cc -nodtk"
-
-   On Solaris, don't put '/usr/ucb' early in your 'PATH'.  This
-directory contains several dysfunctional programs; working variants of
-these programs are available in '/usr/bin'.  So, if you need '/usr/ucb'
-in your 'PATH', put it _after_ '/usr/bin'.
-
-   On Haiku, software installed for all users goes in '/boot/common',
-not '/usr/local'.  It is recommended to use the following options:
-
-     ./configure --prefix=/boot/common
-
-Specifying the System Type
-==========================
-
-   There may be some features 'configure' cannot figure out
-automatically, but needs to determine by the type of machine the package
-will run on.  Usually, assuming the package is built to be run on the
-_same_ architectures, 'configure' can figure that out, but if it prints
-a message saying it cannot guess the machine type, give it the
-'--build=TYPE' option.  TYPE can either be a short name for the system
-type, such as 'sun4', or a canonical name which has the form:
-
-     CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
-     OS
-     KERNEL-OS
-
-   See the file 'config.sub' for the possible values of each field.  If
-'config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
-   If you are _building_ compiler tools for cross-compiling, you should
-use the option '--target=TYPE' to select the type of system they will
-produce code for.
-
-   If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with '--host=TYPE'.
-
-Sharing Defaults
-================
-
-   If you want to set default values for 'configure' scripts to share,
-you can create a site shell script called 'config.site' that gives
-default values for variables like 'CC', 'cache_file', and 'prefix'.
-'configure' looks for 'PREFIX/share/config.site' if it exists, then
-'PREFIX/etc/config.site' if it exists.  Or, you can set the
-'CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all 'configure' scripts look for a site script.
-
-Defining Variables
-==================
-
-   Variables not defined in a site shell script can be set in the
-environment passed to 'configure'.  However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost.  In order to avoid this problem, you should set
-them in the 'configure' command line, using 'VAR=value'.  For example:
-
-     ./configure CC=/usr/local2/bin/gcc
-
-causes the specified 'gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-Unfortunately, this technique does not work for 'CONFIG_SHELL' due to
-an Autoconf limitation.  Until the limitation is lifted, you can use
-this workaround:
-
-     CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
-
-'configure' Invocation
-======================
-
-   'configure' recognizes the following options to control how it
-operates.
-
-'--help'
-'-h'
-     Print a summary of all of the options to 'configure', and exit.
-
-'--help=short'
-'--help=recursive'
-     Print a summary of the options unique to this package's
-     'configure', and exit.  The 'short' variant lists options used
-     only in the top level, while the 'recursive' variant lists options
-     also present in any nested packages.
-
-'--version'
-'-V'
-     Print the version of Autoconf used to generate the 'configure'
-     script, and exit.
-
-'--cache-file=FILE'
-     Enable the cache: use and save the results of the tests in FILE,
-     traditionally 'config.cache'.  FILE defaults to '/dev/null' to
-     disable caching.
-
-'--config-cache'
-'-C'
-     Alias for '--cache-file=config.cache'.
-
-'--quiet'
-'--silent'
-'-q'
-     Do not print messages saying which checks are being made.  To
-     suppress all normal output, redirect it to '/dev/null' (any error
-     messages will still be shown).
-
-'--srcdir=DIR'
-     Look for the package's source code in directory DIR.  Usually
-     'configure' can determine that directory automatically.
-
-'--prefix=DIR'
-     Use DIR as the installation prefix.  *note Installation Names::
-     for more details, including other options available for fine-tuning
-     the installation locations.
-
-'--no-create'
-'-n'
-     Run the configure checks, but stop before creating any output
-     files.
-
-'configure' also accepts some other, not widely useful, options.  Run
-'configure --help' for more details.
index b9f067e..72a2813 100644 (file)
@@ -2,9 +2,7 @@ include *.am
 include autogen.sh
 include configure.ac
 include COPYING
-include HACKING
 include *.in
-include INSTALL
 include m4/introspection.m4
 include m4/python.m4
 include NEWS
@@ -15,3 +13,4 @@ recursive-include examples *.py *.am *.png *.css *.ui *.gif *.gresource *.jpg *.
 recursive-include gi *.am *.h
 recursive-include pygtkcompat *.am
 recursive-include tests *.py *.c *.h *.xml *.supp *nouppera *.am
+recursive-include docs *.rst *.svg LICENSE *.ico *.png *.css *.py *.dia Makefile
index 643aefc..c097d9d 100644 (file)
@@ -22,10 +22,10 @@ EXTRA_DIST = \
        m4/introspection.m4 \
        setup.py \
        MANIFEST.in \
-       README.rst
+       README.rst \
+       docs
 
 MAINTAINERCLEANFILES = \
-       $(srcdir)/INSTALL \
        $(srcdir)/aclocal.m4 \
        $(srcdir)/autoscan.log \
        $(srcdir)/compile \
@@ -143,6 +143,7 @@ dist-hook: $(BUILT_EXTRA_DIST)
        for f in $$files; do \
          if test -f $$f; then d=.; else d=$(srcdir); fi; \
          rm -f $(distdir)/$$f && cp $$d/$$f $(distdir) || exit 1; done
+       rm -rf "$(distdir)/docs/_build"
 
 # pycheck_subdirs = 
 
index 9190734..ddf2c59 100644 (file)
@@ -213,8 +213,8 @@ CSCOPE = cscope
 DIST_SUBDIRS = $(SUBDIRS)
 am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/PKG-INFO.in \
        $(srcdir)/config.h.in $(srcdir)/pygobject-3.0.pc.in COPYING \
-       ChangeLog INSTALL NEWS compile config.guess config.sub \
-       install-sh ltmain.sh missing py-compile
+       ChangeLog NEWS compile config.guess config.sub install-sh \
+       ltmain.sh missing py-compile
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
@@ -456,10 +456,10 @@ EXTRA_DIST = \
        m4/introspection.m4 \
        setup.py \
        MANIFEST.in \
-       README.rst
+       README.rst \
+       docs
 
 MAINTAINERCLEANFILES = \
-       $(srcdir)/INSTALL \
        $(srcdir)/aclocal.m4 \
        $(srcdir)/autoscan.log \
        $(srcdir)/compile \
@@ -1177,6 +1177,7 @@ dist-hook: $(BUILT_EXTRA_DIST)
        for f in $$files; do \
          if test -f $$f; then d=.; else d=$(srcdir); fi; \
          rm -f $(distdir)/$$f && cp $$d/$$f $(distdir) || exit 1; done
+       rm -rf "$(distdir)/docs/_build"
 
 # pycheck_subdirs = 
 
diff --git a/NEWS b/NEWS
index b663a0a..4185039 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,14 @@
+3.27.1  11-Dec-2017
+        - Revert "setup.py: Also set setup_requires to require pycairo" (Christoph Reiter)
+        - setup.py: Also set setup_requires to require pycairo (Christoph Reiter)
+        - setup.py: Provide a os.path.samefile fallback for Python 2 under Windows (Christoph Reiter)
+        - Add sphinx based documentation (Christoph Reiter) (#791448)
+        - PKG-INFO: Revert name back to PyGObject (Christoph Reiter)
+        - setup.py: Rework pycairo discovery to not use pkg-config (Christoph Reiter)
+        - setup.py: Fix the distcheck command on Windows (Christoph Reiter)
+        - setup.py: Remove various classifiers and the download-url which aren't accepted by pypi (Christoph Reiter)
+        - version bump (Christoph Reiter)
+
 3.27.0  08-Dec-2017
         - demo: pep8 fixes (Christoph Reiter)
         - Fix ctypes.PyDLL construction under Windows (Christoph Reiter) (#622084)
index 279cc40..89b65b4 100644 (file)
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
-Name: pygobject
-Version: 3.27.0
+Name: PyGObject
+Version: 3.27.1
 Summary: Python bindings for GObject Introspection
 Home-page: https://pygobject.readthedocs.io
 Author: James Henstridge
@@ -8,14 +8,9 @@ Author-email: james@daa.com.au
 Maintainer: Simon Feltman
 Maintainer-email: sfeltman@src.gnome.org
 License: GNU LGPL
-Download-url: ftp://ftp.gnome.org/pub/GNOME/sources/pygobject/3.27/pygobject-3.27.0.tar.gz
 Description: Python bindings for GObject Introspection
 Platform: POSIX, Windows
 Classifier: Development Status :: 5 - Production/Stable
-Classifier: Environment :: Linux
-Classifier: Environment :: MacOS X
-Classifier: Environment :: Win32 (MS Windows)
-Classifier: Environment :: Unix
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
 Classifier: Operating System :: POSIX
index bebaf08..c357cc3 100644 (file)
@@ -1,5 +1,5 @@
 Metadata-Version: 1.0
-Name: pygobject
+Name: PyGObject
 Version: @VERSION@
 Summary: Python bindings for GObject Introspection
 Home-page: https://pygobject.readthedocs.io
@@ -8,14 +8,9 @@ Author-email: james@daa.com.au
 Maintainer: Simon Feltman
 Maintainer-email: sfeltman@src.gnome.org
 License: GNU LGPL
-Download-url: ftp://ftp.gnome.org/pub/GNOME/sources/pygobject/@PYGOBJECT_MAJOR_VERSION@.@PYGOBJECT_MINOR_VERSION@/pygobject-@VERSION@.tar.gz
 Description: Python bindings for GObject Introspection
 Platform: POSIX, Windows
 Classifier: Development Status :: 5 - Production/Stable
-Classifier: Environment :: Linux
-Classifier: Environment :: MacOS X
-Classifier: Environment :: Win32 (MS Windows)
-Classifier: Environment :: Unix
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
 Classifier: Operating System :: POSIX
index 7eb7c8b..c163301 100644 (file)
-=========
-PyGObject
-=========
+.. image:: https://pygobject.readthedocs.io/en/latest/_images/pygobject.svg
+   :align: center
+   :width: 400px
+   :height: 98px
 
-This archive contains bindings for the GLib, and GObject,
-to be used in Python. It is a fairly complete set of bindings,
-it's already rather useful, and is usable to write moderately
-complex programs.  (see the examples directory for some examples
-of the simpler programs you could write).
+|
 
-If you have any enhancements or bug reports, please file them in
-bugzilla at:
+**PyGObject** is a Python package which provides bindings for `GObject
+<https://developer.gnome.org/gobject/stable/>`__ based libraries such as `GTK+
+<https://www.gtk.org/>`__, `GStreamer <https://gstreamer.freedesktop.org/>`__,
+`WebKitGTK+ <https://webkitgtk.org/>`__, `GLib
+<https://developer.gnome.org/glib/stable/>`__, `GIO
+<https://developer.gnome.org/gio/stable/>`__ and many more.
 
-    http://bugzilla.gnome.org/enter_bug.cgi?product=pygobject
+It supports Linux, Windows and macOS and works with **Python 2.7+** as well as
+**Python 3.4+**. PyGObject, including this documentation, is licensed under
+the **LGPLv2.1+**.
 
-If you have a patch, file the bug first and then use the "create new
-attachment" link on the bug's info page.  My preferred format for
-patches is unified diff format (ie. diff -u).  Please don't send me
-diffs which don't have any context, as these make it very difficult to
-see what the patch does.
+----
 
-
-New Versions
-============
-
-New versions of this package can be found at:
-
-    http://ftp.gnome.org/pub/GNOME/sources/pygobject/
-
-
-Mailing list
-============
-
-pygobject development is discussed on the GNOME python-hackers mailing list.
-You can subscribe to it through the web interface:
-
-  https://mail.gnome.org/mailman/listinfo/python-hackers-list/
-
-
-Requirements
-============
-
-  * C compiler (GCC and MSVC supported)
-  * Python 2.7 or higher
-  * Glib/Gio 2.38.0 or higher
-  * gobject-introspection 1.46.0 or higher
-  * libffi (optional)
-
-
-Copyright Information
-=====================
-
-This software is covered by the GNU Lesser General Public Licence
-(version 2.1, or if you choose, a later version).  Basically just don't
-say you wrote bits you didn't.
-
-
-Compilation
-===========
-
-PyGObject uses the standard autotools for the build infrastructure.  To
-build, it should be as simple as running::
-
-    $ ./configure --prefix=<prefix where python is installed>
-    $ make
-    $ make install
-
-By default, configure searches for a few well-known Python interpreter
-names, such as "python3", "python2", "python2.7", or "python".  If your
-Python interpreter isn't in the path, or is not called "python", you can
-configure pygobject to build against that with --with-python=<path> or
-setting the PYTHON environment variable::
-
-    $ ./configure --with-python=python3
-    $ PYTHON=python3.2 ./configure
-    $ ./configure --with-python=~/my-patched-python/python
-
-If configure can't find GTK+, you may need to set the PKG_CONFIG_PATH
-environment variable to help it find the libraries.
-
-The "make install" target will generate normal and optimised bytecode
-for all the .py files.
-
-Note. If you're installing to another prefix than the one where python
-is installed you'll need to set the PYTHONPATH variable to the
-$prefix/lib/pythonX.Y/site-packages directory created by
-the PyGObject installation.
-
-
-Tests
-=====
-
-After having compiled and installed pygobject, you may want to test them.
-There are a number of example programs available in the examples/
-subdirectory.
-
-
-Getting Help
-============
-
-If you have questions about programming with PyGObject, you might want to
-check the documentation on
-
-    https://live.gnome.org/PyGObject/
-
-If that does not help, send a message to the mailing list (information on
-subscribing is above), or join #python on irc.gnome.org.
-
-
-Authors
-=======
-
-Original authors:
-    * James Henstridge <james@daa.com.au>
-    * Johan Dahlin <johan@gnome.org>
-
-Current maintainers:
-    * Tomeu Vizoso <tomeu.vizoso@collabora.co.uk>
-    * Martin Pitt <martinpitt@gnome.org>
-    * Paolo Borelli <pborelli@gnome.org>
-    * Ignacio Casal Quinteiro <icq@gnome.org>
-    * Sebastian Pölsterl <sebp@k-d-w.org>
-    * Simon Feltman <sfeltman@gnome.org>
-    * Christoph Reiter <reiter.christoph@gmail.com>
-
-See the NEWS file and the git history for a list of all contributors.
+For more information visit https://pygobject.readthedocs.io
index 50ea09e..43a70a0 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for pygobject 3.27.0.
+# Generated by GNU Autoconf 2.69 for pygobject 3.27.1.
 #
 # Report bugs to <http://bugzilla.gnome.org/enter_bug.cgi?product=pygobject>.
 #
@@ -591,8 +591,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='pygobject'
 PACKAGE_TARNAME='pygobject'
-PACKAGE_VERSION='3.27.0'
-PACKAGE_STRING='pygobject 3.27.0'
+PACKAGE_VERSION='3.27.1'
+PACKAGE_STRING='pygobject 3.27.1'
 PACKAGE_BUGREPORT='http://bugzilla.gnome.org/enter_bug.cgi?product=pygobject'
 PACKAGE_URL='https://wiki.gnome.org/Projects/PyGObject/'
 
@@ -1419,7 +1419,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures pygobject 3.27.0 to adapt to many kinds of systems.
+\`configure' configures pygobject 3.27.1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1490,7 +1490,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of pygobject 3.27.0:";;
+     short | recursive ) echo "Configuration of pygobject 3.27.1:";;
    esac
   cat <<\_ACEOF
 
@@ -1635,7 +1635,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-pygobject configure 3.27.0
+pygobject configure 3.27.1
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1913,7 +1913,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by pygobject $as_me 3.27.0, which was
+It was created by pygobject $as_me 3.27.1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2291,9 +2291,9 @@ $as_echo "#define PYGOBJECT_MINOR_VERSION 27" >>confdefs.h
 PYGOBJECT_MINOR_VERSION=27
 
 
-$as_echo "#define PYGOBJECT_MICRO_VERSION 0" >>confdefs.h
+$as_echo "#define PYGOBJECT_MICRO_VERSION 1" >>confdefs.h
 
-PYGOBJECT_MICRO_VERSION=0
+PYGOBJECT_MICRO_VERSION=1
 
 
 ac_config_headers="$ac_config_headers config.h"
@@ -2813,7 +2813,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='pygobject'
- VERSION='3.27.0'
+ VERSION='3.27.1'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -16934,7 +16934,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by pygobject $as_me 3.27.0, which was
+This file was extended by pygobject $as_me 3.27.1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -17001,7 +17001,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-pygobject config.status 3.27.0
+pygobject config.status 3.27.1
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
index cdecad2..f55a54a 100644 (file)
@@ -18,7 +18,7 @@ m4_define(python3_min_ver, 3.4)
 dnl the pygobject version number
 m4_define(pygobject_major_version, 3)
 m4_define(pygobject_minor_version, 27)
-m4_define(pygobject_micro_version, 0)
+m4_define(pygobject_micro_version, 1)
 m4_define(pygobject_version, pygobject_major_version.pygobject_minor_version.pygobject_micro_version)
 
 dnl versions of packages we require ...
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644 (file)
index 0000000..7b13225
--- /dev/null
@@ -0,0 +1,16 @@
+DIAS = $(wildcard images/*.dia)
+DIA_SVGS = $(patsubst %.dia,%.svg,$(DIAS))
+
+all: _build
+
+images/%.svg: images/%.dia
+       dia $< --export=$@ --filter=dia-svg
+
+_build: Makefile *.rst devguide/*.rst guide/*.rst conf.py images/*.png $(DIA_SVGS) ../README.rst
+       sphinx-build -b html . _build
+
+linkcheck:
+       sphinx-build -b linkcheck -n . _build
+
+clean:
+       rm -R _build
diff --git a/docs/changelog.rst b/docs/changelog.rst
new file mode 100644 (file)
index 0000000..2c4f6b1
--- /dev/null
@@ -0,0 +1,10 @@
+Changelog
+=========
+
+Versions with an odd minor version are unstable releases (e.g. 3.27.x) while
+versions with even minor version are stable releases (e.g. 3.28.x)
+
+For more details see the GIT log: https://git.gnome.org//browse/pygobject/log
+
+.. include:: ../NEWS
+    :code:
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644 (file)
index 0000000..aff0fff
--- /dev/null
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+
+extensions = [
+    'sphinx.ext.todo',
+    'sphinx.ext.intersphinx',
+    'sphinx.ext.extlinks',
+]
+
+intersphinx_mapping = {
+    'gtk': ('https://lazka.github.io/pgi-docs/Gtk-3.0', None),
+    'gobject': ('https://lazka.github.io/pgi-docs/GObject-2.0', None),
+    'glib': ('https://lazka.github.io/pgi-docs/GLib-2.0', None),
+    'gdk': ('https://lazka.github.io/pgi-docs/Gdk-3.0', None),
+    'gio': ('https://lazka.github.io/pgi-docs/Gio-2.0', None),
+    'python2': ('https://docs.python.org/2.7', None),
+    'python3': ('https://docs.python.org/3', None),
+}
+
+source_suffix = '.rst'
+master_doc = 'index'
+exclude_patterns = ['_build', 'README.rst']
+
+pygments_style = 'tango'
+html_theme = 'sphinx_rtd_theme'
+html_show_copyright = False
+html_favicon = "images/favicon.ico"
+project = "PyGObject"
+html_title = project
+
+html_context = {
+    'extra_css_files': [
+        'https://quodlibet.github.io/fonts/font-mfizz.css',
+        '_static/extra.css',
+    ],
+}
+
+html_static_path = [
+    "extra.css",
+    "images/pygobject-small.svg",
+]
+
+html_theme_options = {
+    "display_version": False,
+}
+
+extlinks = {
+    'gnomebug': ('https://bugzilla.gnome.org/show_bug.cgi?id=%s', '#'),
+}
+
+suppress_warnings = ["image.nonlocal_uri"]
diff --git a/docs/contact.rst b/docs/contact.rst
new file mode 100644 (file)
index 0000000..f41de73
--- /dev/null
@@ -0,0 +1,11 @@
+=======
+Contact
+=======
+
+**IRC**
+    #python on irc.gnome.org
+
+    Logs for the channel: https://quodlibet.duckdns.org/irc/pygobject
+
+**Mailinglist**
+    https://mail.gnome.org/mailman/listinfo/python-hackers-list
diff --git a/docs/devguide/building_testing.rst b/docs/devguide/building_testing.rst
new file mode 100644 (file)
index 0000000..87f8600
--- /dev/null
@@ -0,0 +1,56 @@
+==================
+Building & Testing
+==================
+
+Building with Autotools
+-----------------------
+
+Building for Python 2:
+
+::
+
+    ./autogen.sh --with-python=python2
+    make
+
+Building for Python 3:
+
+::
+
+    ./autogen.sh --with-python=python3
+    make
+
+
+Building with Setuptools
+------------------------
+
+Building in the source directory:
+
+::
+
+    python setup.py buildext --inplace
+
+
+Testing
+-------
+
+To run the test suite::
+
+    make check
+
+To test only a specific file/class/function::
+
+    make check TEST_NAMES=test_gi
+    make check TEST_NAMES=test_gi.TestUtf8
+    make check TEST_NAMES=test_gi.TestUtf8.test_utf8_full_return
+
+To execute all the tests in a gdb session::
+
+    make check.gdb
+
+To executes all the tests in valgrind::
+
+    make check.valgrind
+
+To execute pyflakes and pep8 tests::
+
+    make check.quality
diff --git a/docs/devguide/dev_environ.rst b/docs/devguide/dev_environ.rst
new file mode 100644 (file)
index 0000000..4d3985f
--- /dev/null
@@ -0,0 +1,46 @@
+.. include:: ../icons.rst
+
+==================================
+Creating a Development Environment
+==================================
+
+This describes how to work on PyGObject itself. Please follow the instructions
+on ":ref:`gettingstarted`" first, as they are a pre-requirement.
+
+
+|ubuntu-logo| Ubuntu / |debian-logo| Debian
+-------------------------------------------
+
+.. code:: console
+
+    sudo apt build-dep pygobject
+    sudo apt install autoconf-archive
+    git clone https://git.gnome.org/browse/pygobject
+    cd pygobject
+    ./autogen.sh
+    make
+    make check
+
+
+|windows-logo| Windows
+----------------------
+
+.. code:: console
+
+    pacman -S --needed --noconfirm base-devel mingw-w64-i686-toolchain git \
+        mingw-w64-i686-python3 mingw-w64-i686-python3-cairo \
+        mingw-w64-i686-gobject-introspection mingw-w64-i686-gtk3 \
+        mingw-w64-i686-libffi autoconf-archive
+    git clone https://git.gnome.org/browse/pygobject
+    cd pygobject
+    ./autogen.sh
+    make
+    make check
+
+
+|macosx-logo| macOS
+-------------------
+
+.. code:: console
+
+    # TODO
diff --git a/docs/devguide/index.rst b/docs/devguide/index.rst
new file mode 100644 (file)
index 0000000..0458eda
--- /dev/null
@@ -0,0 +1,13 @@
+=================
+Development Guide
+=================
+
+.. toctree::
+    :titlesonly:
+    :maxdepth: 1
+
+    overview
+    dev_environ
+    building_testing
+    style_guide
+    override_guidelines
diff --git a/docs/devguide/override_guidelines.rst b/docs/devguide/override_guidelines.rst
new file mode 100644 (file)
index 0000000..9315a69
--- /dev/null
@@ -0,0 +1,90 @@
+==========================
+Python Override Guidelines
+==========================
+
+This document serves as a guide for developers creating new PyGObject
+overrides or modifying existing ones. This document is not intended as hard
+rules as there may always be pragmatic exceptions to what is listed here. It
+is also a good idea to study the `Zen of Python by Tim Peters
+<https://www.python.org/dev/peps/pep-0020/>`__.
+
+In general, overrides should be minimized and preference should always be
+placed on updating the underlying API to be more bindable, adding features to
+GI to support the requirement, or adding mechanical features to PyGObject
+which can apply generically to all overrides (:gnomebug:`721226` and
+:gnomebug:`640812`).
+
+If a GI feature or more bindable API for a library is in the works, it is a
+good idea to avoid the temptation to add temporary short term workarounds in
+overrides. The reason is this can creaste unnecessary conflicts when the
+bindable API becomes a reality (:gnomebug:`707280`).
+
+* Minimize class overrides when possible.
+
+  *Reason*: Class overrides incur a load time performance penalty because
+  they require the classes GType and all of the Python method bindings to be
+  created. See :gnomebug:`705810`
+
+* Prefer monkey patching methods on repository classes over inheritance.
+
+  *Reason*: Class overrides add an additional level to the method
+  resolution order (mro) which has a performance penalty. Since overrides are
+  designed for specific repository library APIs, monkey patching is
+  reasonable because it is utilized in a controlled manner by the API
+  designer (as opposed to monkey patching a third-party library which is more
+  fragile).
+
+* Avoid overriding ``__init__``
+  *Reason*: Sub-classing the overridden class then becomes challenging and
+  has the potential to cause bugs (see :gnomebug:`711487` and reasoning
+  listed in https://wiki.gnome.org/Projects/PyGObject/InitializerDeprecations).
+
+* Unbindable functions which take variadic arguments are generally ok to add
+  Python implementations, but keep in mind the prior noted guidelines. A lot
+  of times adding bindable versions of the functions to the underlying library
+  which take a list is acceptable. For example: :gnomebug:`706119`. Another
+  problem here is if an override is added, then later a bindable version of
+  the API is added which takes a list, there is a good chance we have to live
+  with the override forever which masks a working version implemented by GI.
+
+* Avoid side effects beyond the intended repositories API in function/method
+  overrides.
+
+  *Reason*: This conflates the original API and adds a documentation burden
+  on the override maintainer.
+
+* Don't change function signatures from the original API and don't add default
+  values.
+
+  *Reason*: This turns into a documentation discrepancy between the libraries
+  API and the Python version of the API. Default value work should focus on
+  bug :gnomebug:`558620`, not cherry-picking individual Python functions and
+  adding defaults.
+
+* Avoid implicit side effects to the Python standard library (or anywhere).
+
+  * Don't modify or use sys.argv
+
+    *Reason*: sys.argv should only be explicitly controlled by application
+    developers. Otherwise it requires hacks to work around a module modifying
+    or using the developers command line args which they rightfully own.
+
+    .. code:: python
+
+        saved_argv = sys.argv.copy()
+        sys.argv = []
+        from gi.repository import Gtk
+        sys.argv = saved_argv
+
+  * Never set Pythons default encoding.
+
+    *Reason*: Read or watch Ned Batchelders "`Pragmatic Unicode
+    <https://nedbatchelder.com/text/unipain.html>`__"
+
+* For PyGTK compatibility APIs, add them to PyGTKCompat not overrides.
+* Prefer adapter patterns over of inheritance and overrides.
+
+  *Reason*: An adapter allows more flexibility and less dependency on
+  overrides. It allows application developers to use the raw GI API without
+  having to think about if a particular typelibs overrides have been installed
+  or not.
diff --git a/docs/devguide/overview.rst b/docs/devguide/overview.rst
new file mode 100644 (file)
index 0000000..28527b6
--- /dev/null
@@ -0,0 +1,32 @@
+========
+Overview
+========
+
+
+Bug Tracker
+-----------
+
+You can search through the GNOME Bugzilla for existing bug reports:
+https://bugzilla.gnome.org/page.cgi?id=browse.html&product=pygobject
+
+You can also file a new bug report:
+https://bugzilla.gnome.org/enter_bug.cgi?product=pygobject
+
+
+Git Repos
+---------
+
+PyGObject itself is hosted at https://git.gnome.org/browse/pygobject/
+
+In addition a GitHub organization exists which contains various related
+projects: https://github.com/pygobject
+
+
+Continuous Testing
+------------------
+
+The test suite gets regularly run on all supported platforms using
+https://github.com/pygobject/pygobject-ci
+
+There is currently no integration with bugzilla/git.gnome.org for this and the
+status has to be checked manually.
diff --git a/docs/devguide/style_guide.rst b/docs/devguide/style_guide.rst
new file mode 100644 (file)
index 0000000..0cd01fd
--- /dev/null
@@ -0,0 +1,101 @@
+================
+Style Guidelines
+================
+
+Python Code
+-----------
+
+* Generally follow Python's `PEP8
+  <https://www.python.org/dev/peps/pep-0008/>`__ style guidelines. We run the
+  pep8 command to verify this during unittest runs.
+
+* Break up logical blocks of related code with a newline. Specifically add a
+  blank newline after conditional or looping blocks.
+* Don't comment what is obvious. Instead prefer meaningful names of functions
+  and variables:
+
+  .. code:: python
+
+        # Get the functions signal annotations <-- this comment is unnecessary
+        return_type, arg_types = get_signal_annotations(func)
+
+* Use comments to explain non-obvious blocks and conditionals, magic,
+  workarounds (with bug references), or generally complex pieces of code.
+  Good examples:
+
+  .. code:: python
+
+        # If a property was defined with a decorator, it may already have
+        # a name; if it was defined with an assignment (prop = Property(...))
+        # we set the property's name to the member name
+        if not prop.name:
+            prop.name = name
+
+  .. code:: python
+
+        # Python causes MRO's to be calculated starting with the lowest
+        # base class and working towards the descendant, storing the result
+        # in __mro__ at each point. Therefore at this point we know that
+        # we already have our base class MRO's available to us, there is
+        # no need for us to (re)calculate them.
+        if hasattr(base, '__mro__'):
+            bases_of_subclasses += [list(base.__mro__)]
+
+
+Python Doc Strings
+------------------
+
+* Doc strings should generally follow
+  `PEP257 <https://www.python.org/dev/peps/pep-0257/>`__ unless noted here.
+* Use `reStructuredText (resST) <http://sphinx-doc.org/rest.html>`__
+  annotations.
+* Use three double quotes for doc strings (``"""``).
+* Use a brief description on the same line as the triple quote.
+* Include function parameter documentation (including types, returns, and
+  raises) between the brief description and the full description. Use a
+  newline with indentation for the parameters descriptions.
+
+  .. code:: python
+
+        def spam(amount):
+            """Creates a Spam object with the given amount.
+
+            :param int amount:
+                The amount of spam.
+            :returns:
+                A new Spam instance with the given amount set.
+            :rtype: Spam
+            :raises ValueError:
+                If amount is not a numeric type.
+
+            More complete description.
+            """
+
+* For class documentation, use the classes doc string for an explanation of
+  what the class is used for and how it works, including Python examples.
+  Include ``__init__`` argument documentation after the brief description in
+  the classes doc string. The class ``__init__`` should generally be the first
+  method defined in a class putting it as close as possible (location wise) to
+  the class documentation.
+
+  .. code:: python
+
+        class Bacon(CookedFood):
+            """Bacon is a breakfast food.
+
+            :param CookingType cooking_type:
+                Enum for the type of cooking to use.
+            :param float cooking_time:
+                Amount of time used to cook the Bacon in minutes.
+
+            Use Bacon in combination with other breakfast foods for
+            a complete breakfast. For example, combine Bacon with
+            other items in a list to make a breakfast:
+
+            .. code-block:: python
+
+                breakfast = [Bacon(), Spam(), Spam(), Eggs()]
+
+            """
+            def __init__(self, cooking_type=CookingType.BAKE, cooking_time=15.0):
+                super(Bacon, self).__init__(cooking_type, cooking_time)
diff --git a/docs/extra.css b/docs/extra.css
new file mode 100644 (file)
index 0000000..3ae7bdb
--- /dev/null
@@ -0,0 +1,57 @@
+.wy-side-nav-search {
+    background-color: initial;
+}
+
+.wy-nav-top {
+    background-color: #171A2F;
+}
+
+.wy-side-nav-search input[type="text"] {
+    border-color: transparent;
+}
+
+.wy-nav-content {
+    margin: initial;
+}
+
+.wy-nav-side {
+    background-color: #171A2F;
+}
+
+.rst-content div[role=navigation], footer {
+   font-size: 0.85em;
+   color: #999;
+}
+
+.rst-content div[role=navigation] hr {
+    margin-top: 6px;
+}
+
+footer hr {
+    margin-bottom: 6px;
+}
+
+.rst-footer-buttons {
+    display: none;
+}
+
+a.icon-home, a.icon-home:hover {
+    display: inline-block;
+    padding: 4px 4px 4px 21px;
+    background: transparent url(pygobject-small.svg) center left no-repeat;
+    background-size: 1.2em;
+    margin-top: 0.2em;
+    margin-bottom: 1em;
+}
+
+
+.fa-home::before, .icon-home::before {
+    content: "";
+}
+
+.wy-nav-top a {
+    margin: -2em;
+    background: transparent url(pygobject-small.svg) center left no-repeat;
+    background-size: 1.2em;
+    padding: 4px 4px 4px 24px;
+}
diff --git a/docs/further.rst b/docs/further.rst
new file mode 100644 (file)
index 0000000..832cf45
--- /dev/null
@@ -0,0 +1,10 @@
+=================
+Further Resources
+=================
+
+`Python GTK+ 3 Tutorial <https://python-gtk-3-tutorial.readthedocs.io>`__
+    Many examples showing how to build an application using PyGObject and GTK+.
+
+`Python GI API Reference <https://lazka.github.io/pgi-docs>`__
+    Auto generated API documentation for many libraries accessible through
+    PyGObject.
diff --git a/docs/getting_started.rst b/docs/getting_started.rst
new file mode 100644 (file)
index 0000000..c6e95b2
--- /dev/null
@@ -0,0 +1,128 @@
+.. include:: icons.rst
+
+.. _gettingstarted:
+
+===============
+Getting Started
+===============
+
+To get things started we will try to run a very simple `GTK+
+<https://www.gtk.org/>`_ based GUI application using the :doc:`PyGObject <index>` provided
+Python bindings. First create a small Python script called ``hello.py`` with
+the following content and save it somewhere:
+
+.. code:: python
+
+    import gi
+    gi.require_version("Gtk", "3.0")
+    from gi.repository import Gtk
+
+    window = Gtk.Window(title="Hello World")
+    window.show()
+    window.connect("destroy", Gtk.main_quit)
+    Gtk.main()
+
+Before we can run the example application we need to install PyGObject, GTK+
+and their dependencies. Follow the instructions for your platform below.
+
+======================================= ==================================== ==================================== ==========================================
+|ubuntu-logo| :ref:`Ubuntu <ubuntu>`    |fedora-logo| :ref:`Fedora <fedora>` |arch-logo| :ref:`Arch Linux <arch>` |opensuse-logo| :ref:`openSUSE <opensuse>`
+|windows-logo| :ref:`Windows <windows>` |macosx-logo| :ref:`macOS <macosx>`  |python-logo| :ref:`PyPI <pypi>`
+======================================= ==================================== ==================================== ==========================================
+
+
+.. _windows:
+
+|windows-logo| Windows
+----------------------
+
+1) Go to http://www.msys2.org/ and download the x86_64 installer
+2) Follow the instructions on the page for setting up the basic environment
+3) Run ``C:\msys64\mingw32.exe`` - a terminal window should pop up
+4) Execute ``pacman -S mingw-w64-i686-gtk3 mingw-w64-i686-python2-gobject mingw-w64-i686-python3-gobject``
+5) To test that GTK+3 is working you can run ``gtk3-demo``
+6) Copy the ``hello.py`` script you created to ``C:\msys64\home\<username>``
+7) In the mingw32 terminal execute ``python2 hello.py`` - a window should appear.
+
+.. figure:: images/start_windows.png
+    :scale: 60%
+
+
+.. _ubuntu:
+
+|ubuntu-logo| Ubuntu / |debian-logo| Debian
+-------------------------------------------
+
+1) Open a terminal
+2) Execute ``sudo apt install python-gi python-gi-cairo python3-gi python3-gi-cairo gir1.2-gtk-3.0``
+3) Change the directory to where your ``hello.py`` script can be found (e.g. ``cd Desktop``)
+4) Run ``python2 hello.py``
+
+.. figure:: images/start_linux.png
+    :scale: 60%
+
+
+.. _fedora:
+
+|fedora-logo| Fedora
+--------------------
+
+1) Open a terminal
+2) Execute ``sudo dnf install pygobject3 python3-gobject gtk3``
+3) Change the directory to where your ``hello.py`` script can be found (e.g. ``cd Desktop``)
+4) Run ``python2 hello.py``
+
+
+.. _arch:
+
+|arch-logo| Arch Linux
+----------------------
+
+1) Open a terminal
+2) Execute ``sudo pacman -S python-gobject python2-gobject gtk3``
+3) Change the directory to where your ``hello.py`` script can be found (e.g. ``cd Desktop``)
+4) Run ``python2 hello.py``
+
+
+.. _opensuse:
+
+|opensuse-logo| openSUSE
+------------------------
+
+1) Open a terminal
+2) Execute ``sudo zypper install python-gobject python3-gobject gtk3``
+3) Change the directory to where your ``hello.py`` script can be found (e.g. ``cd Desktop``)
+4) Run ``python2 hello.py``
+
+
+.. _macosx:
+
+|macosx-logo| macOS
+-------------------
+
+1) Go to https://brew.sh/ and install homebrew
+2) Open a terminal
+3) Execute ``brew install pygobject3 --with-python3 gtk+3`` to install for both python2 and python3
+4) Change the directory to where your ``hello.py`` script can be found (e.g. ``cd Desktop``)
+5) Run ``python2 hello.py``
+
+.. figure:: images/start_macos.png
+    :scale: 70%
+
+
+.. _pypi:
+
+|python-logo| From PyPI
+-----------------------
+
+PyGObject is also available on PyPI: https://pypi.org/project/PyGObject
+
+For this approach you have to make sure that all runtime and build
+dependencies are present yourself as pip will only take care of pycairo.
+
+.. code::
+
+    virtualenv --python=python3 myvenv
+    source myvenv/bin/activate
+    pip install pygobject
+    python hello.py
diff --git a/docs/guide/api/api.rst b/docs/guide/api/api.rst
new file mode 100644 (file)
index 0000000..c5e019f
--- /dev/null
@@ -0,0 +1,75 @@
+================
+GI Documentation
+================
+
+This is the API provided by the toplevel "gi" package.
+
+
+.. function:: gi.require_version(namespace, version)
+
+    :param str namespace: The namespace
+    :param str version: The version of the namespace which should be loaded
+    :raises: :obj:`ValueError <exceptions.ValueError>`
+
+    Ensures the namespace gets loaded with the given version. If the namespace
+    was already loaded with a different version or a different version was
+    required previously raises ValueError.
+
+    ::
+
+        import gi
+        gi.require_version('Gtk', '3.0')
+
+
+.. function:: gi.require_foreign(namespace, symbol=None)
+
+    :param str namespace:
+        Introspection namespace of the foreign module (e.g. "cairo")
+    :param symbol:
+        Optional symbol typename to ensure a converter exists.
+    :type symbol: :obj:`str` or :obj:`None`
+    :raises: :obj:`ImportError <exceptions.ImportError>`
+
+    Ensure the given foreign marshaling module is available and loaded.
+
+    Example:
+
+    .. code-block:: python
+
+        import gi
+        import cairo
+        gi.require_foreign('cairo')
+        gi.require_foreign('cairo', 'Surface')
+
+
+.. function:: gi.check_version(version)
+
+    :param tuple version: A version tuple
+    :raises: :obj:`ValueError <exceptions.ValueError>`
+
+    Compares the passed in version tuple with the gi version and does nothing
+    if gi version is the same or newer. Otherwise raises ValueError.
+
+
+.. function:: gi.get_required_version(namespace)
+
+    :returns: The version successfully required previously by :func:`gi.require_version` or :obj:`None`
+    :rtype: str or :obj:`None`
+
+
+.. data:: gi.version_info
+    :annotation: = (3, 18, 1)
+
+    The version of PyGObject
+
+
+.. class:: gi.PyGIDeprecationWarning
+
+    The warning class used for deprecations in PyGObject and the included
+    Python overrides. It inherits from DeprecationWarning and is hidden
+    by default.
+
+
+.. class:: gi.PyGIWarning
+
+    Like :class:`gi.PyGIDeprecationWarning` but visible by default.
diff --git a/docs/guide/api/basic_types.rst b/docs/guide/api/basic_types.rst
new file mode 100644 (file)
index 0000000..b41fee9
--- /dev/null
@@ -0,0 +1,53 @@
+===========
+Basic Types
+===========
+
+PyGObject will automatically convert between C types and Python types. In
+cases where it's appropriate it will use default Python types like :obj:`int`,
+:obj:`list`, and :obj:`dict`.
+
+
+Number Types
+------------
+
+All glib integer types get mapped to :obj:`int`, :obj:`long` and :obj:`float`.
+Since the glib integer types are always range limited, conversions from Python
+int/long can fail with :class:`OverflowError`:
+
+.. code:: pycon
+
+    >>> GLib.random_int_range(0, 2**31-1)
+    1684142898
+    >>> GLib.random_int_range(0, 2**31)
+    Traceback (most recent call last):
+      File "<stdin>", line 1, in <module>
+    OverflowError: 2147483648 not in range -2147483648 to 2147483647
+    >>> 
+
+
+Text Types
+----------
+
+In case you use Python 2 then text is utf-8 encoded :obj:`str`, in case of
+Python 3 :obj:`str` is used.
+
+
+Platform String Types
+---------------------
+
+* Windows + Python 2: utf-8 encoded :obj:`str`
+* Windows + Python 3: :obj:`str`
+* Unix + Python 2: :obj:`str`
+* Unix + Python 3: :obj:`str`
+
+On Python 3 there is currently no support for :obj:`bytes`, see `bug 746564
+<https://bugzilla.gnome.org/show_bug.cgi?id=746564>`__ for more details.
+
+
+Other Types
+-----------
+
+* GList <-> :obj:`list`
+* GSList <-> :obj:`list`
+* GHashTable <-> :obj:`dict`
+* arrays <-> :obj:`list`
diff --git a/docs/guide/api/flags_enums.rst b/docs/guide/api/flags_enums.rst
new file mode 100644 (file)
index 0000000..0a90735
--- /dev/null
@@ -0,0 +1,39 @@
+=============
+Flags & Enums
+=============
+
+Flags are subclasses of :class:`GObject.GFlags` and represent bit fields where
+some bits also have names:
+
+.. code:: pycon
+
+    >>> Gtk.DialogFlags.MODAL
+    <flags GTK_DIALOG_MODAL of type Gtk.DialogFlags>
+    >>> Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT
+    <flags GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT of type Gtk.DialogFlags>
+    >>> int(_)
+    3
+    >>> Gtk.DialogFlags(3)
+    <flags GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT of type Gtk.DialogFlags>
+    >>> isinstance(Gtk.DialogFlags.MODAL, Gtk.DialogFlags)
+    True
+    >>>
+
+Bitwise operations on them will produce a value of the same type.
+
+
+Enums are subclasses of :class:`GObject.GEnum` and represent a list of named
+constants:
+
+.. code:: pycon
+
+    >>> Gtk.Align.CENTER
+    <enum GTK_ALIGN_CENTER of type Gtk.Align>
+    >>> int(Gtk.Align.CENTER)
+    3
+    >>> int(Gtk.Align.END)
+    2
+    >>> Gtk.Align(1)
+    <enum GTK_ALIGN_START of type Gtk.Align>
+    >>> isinstance(Gtk.Align.CENTER, Gtk.Align)
+    True
diff --git a/docs/guide/api/gobject.rst b/docs/guide/api/gobject.rst
new file mode 100644 (file)
index 0000000..08c124b
--- /dev/null
@@ -0,0 +1,91 @@
+==============
+GObject.Object
+==============
+
+Compare to other types, :obj:`GObject.Object` has the best integration between
+the GObject and Python type system.
+
+1) It is possible to subclass a :obj:`GObject.Object`. Subclassing
+   creates a new :obj:`GObject.GType` which is connected to the new Python
+   type. This means you can use it with API which takes :obj:`GObject.GType`.
+2) The Python wrapper instance for a :obj:`GObject.Object` is always the same.
+   For the same C instance you will always get the same Python instance.
+
+
+In addition :obj:`GObject.Object` has support for :any:`signals <signals>` and
+:any:`properties <properties>`
+
+.. toctree::
+    :titlesonly:
+    :maxdepth: 1
+    :hidden:
+
+    signals
+    properties
+
+
+Examples
+--------
+
+Subclassing:
+
+.. code:: pycon
+
+    >>> from gi.repository import GObject
+    >>> class A(GObject.Object):
+    ...     pass
+    ... 
+    >>> A()
+    <__main__.A object at 0x7f9113fc3280 (__main__+A at 0x559d9861acc0)>
+    >>> A.__gtype__
+    <GType __main__+A (94135355573712)>
+    >>> A.__gtype__.name
+    '__main__+A'
+    >>> 
+
+In case you want to specify the GType name we have to provide a
+``__gtype_name__``:
+
+.. code:: pycon
+
+    >>> from gi.repository import GObject
+    >>> class B(GObject.Object):
+    ...     __gtype_name__ = "MyName"
+    ... 
+    >>> B.__gtype__
+    <GType MyName (94830143629776)>
+    >>> 
+
+:obj:`GObject.Object` only supports single inheritance, this means you can
+only subclass one :obj:`GObject.Object`, but multiple Python classes:
+
+.. code:: pycon
+
+    >>> from gi.repository import GObject
+    >>> class MixinA(object):
+    ...     pass
+    ... 
+    >>> class MixinB(object):
+    ...     pass
+    ... 
+    >>> class MyClass(GObject.Object, MixinA, MixinB):
+    ...     pass
+    ... 
+    >>> instance = MyClass()
+
+
+Here we can see how we create a :obj:`Gio.ListStore` for our new subclass and
+that we get back the same Python instance we put into it:
+
+.. code:: pycon
+
+    >>> from gi.repository import GObject, Gio
+    >>> class A(GObject.Object):
+    ...     pass
+    ... 
+    >>> store = Gio.ListStore.new(A)
+    >>> instance = A()
+    >>> store.append(instance)
+    >>> store.get_item(0) is instance
+    True
+    >>> 
diff --git a/docs/guide/api/index.rst b/docs/guide/api/index.rst
new file mode 100644 (file)
index 0000000..efeade3
--- /dev/null
@@ -0,0 +1,12 @@
+=============
+API Reference
+=============
+
+.. toctree::
+    :titlesonly:
+    :maxdepth: 1
+
+    api
+    basic_types
+    flags_enums
+    gobject
diff --git a/docs/guide/api/properties.rst b/docs/guide/api/properties.rst
new file mode 100644 (file)
index 0000000..0241109
--- /dev/null
@@ -0,0 +1,119 @@
+==========
+Properties
+==========
+
+Properties are part of a class and are defined through a
+:obj:`GObject.ParamSpec`, which contains the type, name, value range and so
+on.
+
+To find all the registered properties of a class you can use the
+:meth:`GObject.Object.list_properties` class method.
+
+.. code:: pycon
+
+    >>> Gio.Application.list_properties()
+    [<GParamString 'application-id'>, <GParamFlags 'flags'>, <GParamString
+    'resource-base-path'>, <GParamBoolean 'is-registered'>, <GParamBoolean
+    'is-remote'>, <GParamUInt 'inactivity-timeout'>, <GParamObject
+    'action-group'>, <GParamBoolean 'is-busy'>]
+    >>> param = Gio.Application.list_properties()[0]
+    >>> param.name
+    'application-id'
+    >>> param.owner_type
+    <GType GApplication (94881584893168)>
+    >>> param.value_type
+    <GType gchararray (64)>
+    >>> 
+
+The :obj:`GObject.Object` contructor takes multiple properties as keyword
+arguments. Property names usually contain "-" for seperating words. In Python
+you can either use "-" or "_". In this case variable names don't allow "-", so
+we use "_".
+
+.. code:: pycon
+
+    >>> app = Gio.Application(application_id="foo.bar")
+
+To get and set the property value see :meth:`GObject.Object.get_property` and
+:meth:`GObject.Object.set_property`.
+
+.. code:: pycon
+
+    >>> app = Gio.Application(application_id="foo.bar")
+    >>> app
+    <Gio.Application object at 0x7f7499284fa0 (GApplication at 0x564b571e7c00)>
+    >>> app.get_property("application_id")
+    'foo.bar'
+    >>> app.set_property("application_id", "a.b")
+    >>> app.get_property("application-id")
+    'a.b'
+    >>> 
+
+
+Each instance also has a ``props`` attribute which exposes all properties
+as instance attributes:
+
+.. code:: pycon
+
+    >>> from gi.repository import Gtk
+    >>> button = Gtk.Button(label="foo")
+    >>> button.props.label
+    'foo'
+    >>> button.props.label = "bar"
+    >>> button.get_label()
+    'bar'
+    >>> 
+
+
+To track changes of properties, :obj:`GObject.Object` has a special ``notify``
+signal with the property name as the detail string. Note that in this case you
+have to give the real property name and replacing "-" with "_" wont work.
+
+.. code:: pycon
+
+    >>> app = Gio.Application(application_id="foo.bar")
+    >>> def my_func(instance, param):
+    ...     print("New value %r" % instance.get_property(param.name))
+    ... 
+    >>> app.connect("notify::application-id", my_func)
+    11L
+    >>> app.set_property("application-id", "something.different")
+    New value 'something.different'
+    >>> 
+
+You can define your own properties using the :obj:`GObject.Property` decorator,
+which can be used similarly to the builtin Python :any:`property` decorator:
+
+.. function:: GObject.Property(type=None, default=None, nick='', blurb='', \
+    flags=GObject.ParamFlags.READWRITE, minimum=None, maximum=None)
+
+    :param GObject.GType type: Either a GType, a type with a GType or a
+        Python type which maps to a default GType
+    :param object default: A default value
+    :param str nick: Property nickname
+    :param str block: Short description
+    :param GObject.ParamFlags flags: Property configuration flags
+    :param object minimum: Minimum value, depends on the type
+    :param object maximum: Maximum value, depends on the type
+
+
+.. code:: python
+
+    class AnotherObject(GObject.Object):
+        value = 0
+
+        @GObject.Property
+        def prop_pyobj(self):
+            """Read only property."""
+
+            return object()
+
+        @GObject.Property(type=int)
+        def prop_gint(self):
+            """Read-write integer property."""
+
+            return self.value
+
+        @prop_gint.setter
+        def prop_gint(self, value):
+            self.value = value
diff --git a/docs/guide/api/signals.rst b/docs/guide/api/signals.rst
new file mode 100644 (file)
index 0000000..0001862
--- /dev/null
@@ -0,0 +1,93 @@
+=======
+Signals
+=======
+
+GObject signals are a system for registering callbacks for specific events.
+
+To find all signals of a class you can use the
+:func:`GObject.signal_list_names` function:
+
+
+.. code:: pycon
+
+    >>> GObject.signal_list_names(Gio.Application)
+    ('activate', 'startup', 'shutdown', 'open', 'command-line', 'handle-local-options')
+    >>> 
+
+
+To connect to a signal, use :meth:`GObject.Object.connect`:
+
+.. code:: pycon
+
+    >>> app = Gio.Application()
+    >>> def on_activate(instance):
+    ...     print("Activated:", instance)
+    ... 
+    >>> app.connect("activate", on_activate)
+    17L
+    >>> app.run()
+    ('Activated:', <Gio.Application object at 0x7f1bbb304320 (GApplication at 0x5630f1faf200)>)
+    0
+    >>> 
+
+It returns number which identifies the connection during its lifetime and which
+can be used to modify the connection.
+
+For example it can be used to temporarily ignore signal emissions using
+:meth:`GObject.Object.handler_block`:
+
+.. code:: pycon
+
+    >>> app = Gio.Application(application_id="foo.bar")
+    >>> def on_change(*args):
+    ...     print(args)
+    ... 
+    >>> c = app.connect("notify::application-id", on_change)
+    >>> app.props.application_id = "foo.bar"
+    (<Gio.Application object at 0x7f1bbb304550 (GApplication at 0x5630f1faf2b0)>, <GParamString 'application-id'>)
+    >>> with app.handler_block(c):
+    ...     app.props.application_id = "no.change"
+    ... 
+    >>> app.props.application_id = "change.again"
+    (<Gio.Application object at 0x7f1bbb304550 (GApplication at 0x5630f1faf2b0)>, <GParamString 'application-id'>)
+    >>> 
+
+
+You can define your own signals using the :obj:`GObject.Signal` decorator:
+
+
+.. function:: GObject.Signal(name='', flags=GObject.SignalFlags.RUN_FIRST, \
+    return_type=None, arg_types=None, accumulator=None, accu_data=None)
+
+    :param str name: The signal name
+    :param GObject.SignalFlags flags: Signal flags
+    :param GObject.GType return_type: Return type
+    :param list arg_types: List of :class:`GObject.GType` argument types
+    :param GObject.SignalAccumulator accumulator: Accumulator function
+    :param object accu_data: User data for the accumulator
+
+
+.. code:: python
+
+    class MyClass(GObject.Object):
+
+        @GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, return_type=bool,
+                        arg_types=(object,),
+                        accumulator=GObject.signal_accumulator_true_handled)
+        def test(self, *args):
+            print("Handler", args)
+
+        @GObject.Signal
+        def noarg_signal(self):
+            print("noarg_signal")
+
+    instance = MyClass()
+
+    def test_callback(inst, obj):
+        print "Handled", inst, obj
+        return True
+
+    instance.connect("test", test_callback)
+    instance.emit("test", object())
+
+    instance.emit("noarg_signal")
diff --git a/docs/guide/cairo_integration.rst b/docs/guide/cairo_integration.rst
new file mode 100644 (file)
index 0000000..84ea3f3
--- /dev/null
@@ -0,0 +1,39 @@
+=================
+Cairo Integration
+=================
+
+Despite `cairo <https://cairographics.org/>`__ not being a GObject based
+library, PyGObject provides special cairo integration through `pycairo
+<https://pycairo.readthedocs.io>`__. Functions returning and taking cairo data
+types get automatically converted to pycairo objects and vice versa.
+
+Some distros ship the PyGObject cairo support in a separate package. If you've
+followed the instructions on ":ref:`gettingstarted`" you should have everything
+installed.
+
+If your application requires the cairo integration you can use
+:func:`gi.require_foreign`:
+
+.. code:: python
+
+    try:
+        gi.require_foreign("cairo")
+    except ImportError:
+        print("No pycairo integration :(")
+
+Note that PyGObject currently does not support `cairocffi
+<https://pypi.python.org/pypi/cairocffi>`__, only pycairo.
+
+
+Demo
+----
+
+The following example shows a :obj:`Gtk.Window` with a custom drawing in Python
+using pycairo.
+
+.. figure:: images/cairo_integration.png
+    :scale: 75%
+    :align: center
+
+.. literalinclude:: code/cairo-demo.py
+    :linenos:
diff --git a/docs/guide/code/cairo-demo.py b/docs/guide/code/cairo-demo.py
new file mode 100755 (executable)
index 0000000..f5ac112
--- /dev/null
@@ -0,0 +1,133 @@
+#!/usr/bin/env python
+"""
+Based on cairo-demo/X11/cairo-demo.c
+"""
+
+import cairo
+import gi
+gi.require_version("Gtk", "3.0")
+from gi.repository import Gtk
+
+SIZE = 30
+
+
+def triangle(ctx):
+    ctx.move_to(SIZE, 0)
+    ctx.rel_line_to(SIZE, 2 * SIZE)
+    ctx.rel_line_to(-2 * SIZE, 0)
+    ctx.close_path()
+
+
+def square(ctx):
+    ctx.move_to(0, 0)
+    ctx.rel_line_to(2 * SIZE, 0)
+    ctx.rel_line_to(0, 2 * SIZE)
+    ctx.rel_line_to(-2 * SIZE, 0)
+    ctx.close_path()
+
+
+def bowtie(ctx):
+    ctx.move_to(0, 0)
+    ctx.rel_line_to(2 * SIZE, 2 * SIZE)
+    ctx.rel_line_to(-2 * SIZE, 0)
+    ctx.rel_line_to(2 * SIZE, -2 * SIZE)
+    ctx.close_path()
+
+
+def inf(ctx):
+    ctx.move_to(0, SIZE)
+    ctx.rel_curve_to(0, SIZE, SIZE, SIZE, 2 * SIZE, 0)
+    ctx.rel_curve_to(SIZE, -SIZE, 2 * SIZE, -SIZE, 2 * SIZE, 0)
+    ctx.rel_curve_to(0, SIZE, -SIZE, SIZE, - 2 * SIZE, 0)
+    ctx.rel_curve_to(-SIZE, -SIZE, - 2 * SIZE, -SIZE, - 2 * SIZE, 0)
+    ctx.close_path()
+
+
+def draw_shapes(ctx, x, y, fill):
+    ctx.save()
+
+    ctx.new_path()
+    ctx.translate(x + SIZE, y + SIZE)
+    bowtie(ctx)
+    if fill:
+        ctx.fill()
+    else:
+        ctx.stroke()
+
+    ctx.new_path()
+    ctx.translate(3 * SIZE, 0)
+    square(ctx)
+    if fill:
+        ctx.fill()
+    else:
+        ctx.stroke()
+
+    ctx.new_path()
+    ctx.translate(3 * SIZE, 0)
+    triangle(ctx)
+    if fill:
+        ctx.fill()
+    else:
+        ctx.stroke()
+
+    ctx.new_path()
+    ctx.translate(3 * SIZE, 0)
+    inf(ctx)
+    if fill:
+        ctx.fill()
+    else:
+        ctx.stroke()
+
+    ctx.restore()
+
+
+def fill_shapes(ctx, x, y):
+    draw_shapes(ctx, x, y, True)
+
+
+def stroke_shapes(ctx, x, y):
+    draw_shapes(ctx, x, y, False)
+
+
+def draw(da, ctx):
+    ctx.set_source_rgb(0, 0, 0)
+
+    ctx.set_line_width(SIZE / 4)
+    ctx.set_tolerance(0.1)
+
+    ctx.set_line_join(cairo.LINE_JOIN_ROUND)
+    ctx.set_dash([SIZE / 4.0, SIZE / 4.0], 0)
+    stroke_shapes(ctx, 0, 0)
+
+    ctx.set_dash([], 0)
+    stroke_shapes(ctx, 0, 3 * SIZE)
+
+    ctx.set_line_join(cairo.LINE_JOIN_BEVEL)
+    stroke_shapes(ctx, 0, 6 * SIZE)
+
+    ctx.set_line_join(cairo.LINE_JOIN_MITER)
+    stroke_shapes(ctx, 0, 9 * SIZE)
+
+    fill_shapes(ctx, 0, 12 * SIZE)
+
+    ctx.set_line_join(cairo.LINE_JOIN_BEVEL)
+    fill_shapes(ctx, 0, 15 * SIZE)
+    ctx.set_source_rgb(1, 0, 0)
+    stroke_shapes(ctx, 0, 15 * SIZE)
+
+
+def main():
+    win = Gtk.Window()
+    win.connect('destroy', lambda w: Gtk.main_quit())
+    win.set_default_size(450, 550)
+
+    drawingarea = Gtk.DrawingArea()
+    win.add(drawingarea)
+    drawingarea.connect('draw', draw)
+
+    win.show_all()
+    Gtk.main()
+
+
+if __name__ == '__main__':
+    main()
diff --git a/docs/guide/debug_profile.rst b/docs/guide/debug_profile.rst
new file mode 100644 (file)
index 0000000..628bab1
--- /dev/null
@@ -0,0 +1,112 @@
+=====================
+Debugging & Profiling
+=====================
+
+Things can go wrong, these tools may help you find the cause. If you know any
+more tricks please share them.
+
+
+GObject Instance Count Leak Check
+---------------------------------
+
+Requires a development (only available in debug mode) version of glib. Jhbuild
+recommended.
+
+::
+
+    jhbuild shell
+    GOBJECT_DEBUG=instance-count GTK_DEBUG=interactive ./quodlibet.py
+
+* In the GTK+ Inspector switch to the "Statistics" tab
+* Sort by "Cumulative" and do the action which you suspect does leak or where
+  you want to make sure it doesn't repeatedly. Like for example opening
+  and closing a window or switching between media files to present.
+* If something in the "Cumulative" column steadily increases there probably
+  is a leak.
+
+cProfile Performance Profiling
+------------------------------
+
+* https://docs.python.org/2/library/profile.html
+* bundled with python
+
+::
+
+    python -m cProfile -s [sort_order] quodlibet.py > cprof.txt
+
+
+where ``sort_order`` can one of the following:
+calls, cumulative, file, line, module, name, nfl, pcalls, stdname, time
+
+Example output::
+
+             885311 function calls (866204 primitive calls) in 12.110 seconds
+
+       Ordered by: cumulative time
+
+       ncalls  tottime  percall  cumtime  percall filename:lineno(function)
+            1    0.002    0.002   12.112   12.112 quodlibet.py:11(<module>)
+            1    0.007    0.007   12.026   12.026 quodlibet.py:25(main)
+    19392/13067    0.151    0.000    4.342    0.000 __init__.py:639(__get__)
+            1    0.003    0.003    4.232    4.232 quodlibetwindow.py:121(__init__)
+            1    0.000    0.000    4.029    4.029 quodlibetwindow.py:549(select_browser)
+            1    0.002    0.002    4.022    4.022 albums.py:346(__init__)
+            ...
+            ...
+
+SnakeViz - cProfile Based Visualization
+---------------------------------------
+
+* https://jiffyclub.github.io/snakeviz/
+* ``pip install snakeviz``
+
+::
+
+    python -m cProfile -o prof.out quodlibet.py
+    snakeviz prof.out
+
+
+Sysprof - System-wide Performance Profiler for Linux
+----------------------------------------------------
+
+* http://sysprof.com/
+
+::
+
+    sysprof-cli -c "python quodlibet/quodlibet.py"
+    sysprof capture.syscap
+
+GDB
+---
+
+::
+
+    gdb --args python quodlibet/quodlibet.py
+    # type "run" and hit enter
+
+
+Debugging Wayland Issues
+------------------------
+
+::
+
+    mutter --nested --wayland
+    # start your app, it should show up in the nested mutter
+
+::
+
+    weston
+    # start your app, it should show up in the nested weston
+
+
+Debugging HiDPI Issue
+---------------------
+
+::
+
+    GDK_SCALE=2 ./quodlibet/quodlibet.py
+
+::
+
+    MUTTER_DEBUG_NUM_DUMMY_MONITORS=2 MUTTER_DEBUG_DUMMY_MONITOR_SCALES=1,2 mutter --nested --wayland
+    # start your app, it should show up in the nested mutter
diff --git a/docs/guide/deploy.rst b/docs/guide/deploy.rst
new file mode 100644 (file)
index 0000000..efee20c
--- /dev/null
@@ -0,0 +1,52 @@
+.. include:: ../icons.rst
+
+======================
+Application Deployment
+======================
+
+There is currently no nice deployment story, but it's not impossible. This is
+a list of random notes and examples.
+
+|linux-logo| Linux
+------------------
+
+On Linux there is no single strategy. Quod Libet uses distutils, MyPaint uses
+SCons. Gramps uses distutils.
+
+|macosx-logo| macOS
+-------------------
+
+On OSX you can use `gtk-osx <https://git.gnome.org/browse/gtk-osx>`__ which is
+based on jhbuild and then `gtk-mac-bundler
+<https://git.gnome.org/browse/gtk-mac-bundler>`__ for packaging things up and
+making libraries relocatable. With macOS bundles you generally have a startup
+shell script which sets all the various env vars relative to the bundle,
+similar to jhbuild.
+
+|windows-logo| Windows
+----------------------
+
+On Windows things are usually build to be relocatable by default, so no env
+vars are needed. You can build/install through MSYS2, copy the bits you need
+and you are done. For GUI application you'll also need an exe launcher that
+links against the python dll.
+
+Example Deployments
+-------------------
+
+* `Quod Libet <https://quodlibet.readthedocs.io/>`__ provides a Windows
+  installer based on MSYS2 and NSIS3. On macOS, jhbuild is used for building,
+  gtk.mac-bundler for packing things up and `dmgbuild
+  <https://pypi.python.org/pypi/dmgbuild>`__ for creating a dmg. distutis is
+  used for building/installing the application into the final environment.
+  Most of this is automated and scripts can be found in the git repo.
+
+* `MyPaint <http://mypaint.org/>`__ provides a Windows installer based on
+  MSYS2 and Inno Setup. It uses SCons for building/installing the application.
+
+* ...?
+
+Other options
+-------------
+
+* `PyInstaller <http://www.pyinstaller.org/>`_ is a program that freezes (packages) Python programs into stand-alone executables, under Windows, Linux, Mac OS X, and more. PyInstaller's packager has built-in support for automatically including PyGObject dependencies with your application without requiring additional configuration.
diff --git a/docs/guide/faq.rst b/docs/guide/faq.rst
new file mode 100644 (file)
index 0000000..48031b0
--- /dev/null
@@ -0,0 +1,11 @@
+==========================
+Frequently Asked Questions
+==========================
+
+How can I use PyGObject with the official CPython builds on Windows?
+--------------------------------------------------------------------
+
+https://sourceforge.net/projects/pygobjectwin32 provides binaries which should
+be ABI compatible with the official CPython binaries. I'd recommend using
+msys2 if at all possible, since there are more people involved and it's easier
+to fix/patch things yourself.
diff --git a/docs/guide/images/cairo_integration.png b/docs/guide/images/cairo_integration.png
new file mode 100644 (file)
index 0000000..4726875
Binary files /dev/null and b/docs/guide/images/cairo_integration.png differ
diff --git a/docs/guide/index.rst b/docs/guide/index.rst
new file mode 100644 (file)
index 0000000..ac966d7
--- /dev/null
@@ -0,0 +1,17 @@
+==========
+User Guide
+==========
+
+
+.. toctree::
+    :titlesonly:
+    :maxdepth: 1
+
+    api/index
+    cairo_integration
+    threading
+    debug_profile
+    deploy
+    testing
+    porting
+    faq
diff --git a/docs/guide/porting.rst b/docs/guide/porting.rst
new file mode 100644 (file)
index 0000000..8ee1134
--- /dev/null
@@ -0,0 +1,109 @@
+============================
+Porting from Static Bindings
+============================
+
+Before PyGObject 3, bindings where not generated automatically through gobject
+introspection and where provided as separate Python libraries like pygobject,
+pygtk, pygst etc. We call them static bindings.
+
+If your code contains imports like ``import gtk``, ``import gst``, ``import
+glib`` or ``import gobject`` you are using the old bindings and you should
+upgrade.
+
+Note that using old and new bindings in the same process is not supported, you
+have to switch everything at once.
+
+
+Static Bindings Library Differences
+-----------------------------------
+
+**pygtk** supported GTK+ 2.0 and Python 2 only. PyGObject supports GTK+ >=3.0
+and Python 2/3. If you port away from pygtk you also have to move to GTK+ 3.0
+at the same time. **pygtkcompat** described below can help you with that
+transition.
+
+**pygst** supports GStreamer 0.10 and Python 2 only. Like with GTK+ you have
+to move to PyGObject and GStreamer 1.0 at the same time.
+
+**pygobject 2** supports glib 2.0 and Python 2. The new bindings also support
+glib 2.0 and Python 2/3.
+
+
+General Porting Tips
+--------------------
+
+PyGObject contains a shell script which can help you with the many naming
+differences between static and dynamic bindings:
+
+https://git.gnome.org/browse/pygobject/plain/tools/pygi-convert.sh
+
+::
+
+    ./pygi-convert.sh mymodule.py
+
+It just does basic text replacement. It reduces the amount of naming changes
+you have to make in the beginning, but nothing more.
+
+1) Run on a Python module
+2) Check/Verify the changes made (e.g. using ``git diff``)
+3) Finish porting the module by hand
+4) Continue to the next module...
+
+
+Porting Tips for GTK+
+---------------------
+
+While PyGObject theoretically supports GTK+ 2.0 it is not really usable. It
+will be easier to port to GTK+ 3.0 right away.
+
+For some general advice regarding the migration from GTK+ 2.0 to 3.0 see the
+`offical migration guide
+<https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html>`__. If you
+need to know how a C symbol is exposed in Python have a look at the `symbol
+mapping listing <https://lazka.github.io/pgi-docs/#Gtk-3.0/mapping.html>`__.
+
+
+Using the pygtkcompat Compatibility Layer
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+PyGObject ships a compatibility layer for pygtk which partially emulates the
+old interfaces:
+
+::
+
+    from gi import pygtkcompat
+    pygtkcompat.enable()
+    pygtkcompat.enable_gtk(version='3.0')
+
+    import gtk
+
+``enable()`` has to be called once before the first ``gtk`` import.
+
+Note that pygtkcompat is just for helping you through the transition by
+allowing you to port one module at a time. Only a limited subset of the
+interfaces are emulated correctly and you should try to get rid of it in the
+end.
+
+
+Default Encoding Changes
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Importing ``gtk`` had the side effect of changing the default Python encoding
+from ASCII to UTF-8 (check ``sys.getdefaultencoding()``) and that no longer
+happens with PyGObject. Since text with pygtk is returned as utf-8 encoded
+str, your code is likely depending auto-decoding in many places and you can
+change it manually by doing:
+
+::
+
+    # Python 2 only
+    import sys
+    reload(sys)
+    sys.setdefaultencoding("utf-8")
+    # see if auto decoding works:
+    assert '\xc3\xb6' + u'' ==  u'\xf6'
+
+While this is not officially supported by Python I don't know of any
+downsides. Once you are sure that you explicitly decode in all places or you
+move to Python 3 where things are unicode by default you can remove this
+again.
diff --git a/docs/guide/testing.rst b/docs/guide/testing.rst
new file mode 100644 (file)
index 0000000..6a7c663
--- /dev/null
@@ -0,0 +1,39 @@
+.. include:: ../icons.rst
+
+==================================
+Testing and Continuous Integration
+==================================
+
+To get automated tests of GTK+ code running on a headless server use Xvfb
+(virtual framebuffer X server). It provides the ``xvfb-run -a`` command which
+creates a temporary X server without the need for any real display hardware.
+
+::
+
+    xvfb-run -a python my_script.py
+
+
+Continuous Integration using Travis CI / CircleCI
+-------------------------------------------------
+
+Travis CI uses a rather old Ubuntu and thus the supported GTK+ is at 3.10 and
+PyGObject is at 3.12. If that's enough for you then have a look at our Travis
+CI example project:
+
+    |github-logo| https://github.com/pygobject/pygobject-travis-ci-examples
+
+    .. image:: https://travis-ci.org/pygobject/pygobject-travis-ci-examples.svg?branch=master
+        :target: https://travis-ci.org/pygobject/pygobject-travis-ci-examples
+
+To get newer PyGObject, GTK+, etc. working on `Travis CI
+<https://travis-ci.org>`__ or `CircleCI <https://circleci.com>`__ you can use
+Docker with an image of your choosing. Have a look at our Docker example
+project which runs tests on various Debian, Ubuntu and Fedora versions:
+
+    |github-logo| https://github.com/pygobject/pygobject-travis-ci-docker-examples
+
+    .. image:: https://travis-ci.org/pygobject/pygobject-travis-ci-docker-examples.svg?branch=master
+        :target: https://travis-ci.org/pygobject/pygobject-travis-ci-docker-examples
+
+    .. image:: https://circleci.com/gh/pygobject/pygobject-travis-ci-docker-examples.svg?style=shield
+        :target: https://circleci.com/gh/pygobject/pygobject-travis-ci-docker-examples
diff --git a/docs/guide/threading.rst b/docs/guide/threading.rst
new file mode 100644 (file)
index 0000000..c1bac32
--- /dev/null
@@ -0,0 +1,290 @@
+=====================
+Threads & Concurrency
+=====================
+
+Operations which could potentially block should not be executed in the main 
+loop. The main loop is in charge of input processing and drawing and 
+blocking it results in the user interface freezing. For the user this means 
+not getting any feedback and not being able to pause or abort the operation 
+which causes the problem.
+
+Such an operation might be:
+
+* Loading external resources like an image file on the web
+* Searching the local file system
+* Writing, reading and copying files
+* Calculations where the runtime depends on some external factor
+
+The following examples show
+
+* how Python threads, running in parallel to GTK+, can interact with the UI
+* how to use and control asynchronous I/O operations in glib
+
+
+Threads
+-------
+
+The first example uses a Python thread to execute code in the background 
+while still showing feedback on the progress in a window.
+
+.. code:: python
+
+    import threading
+    import time
+
+    from gi.repository import GLib, Gtk, GObject
+
+
+    def app_main():
+        win = Gtk.Window(default_height=50, default_width=300)
+        win.connect("destroy", Gtk.main_quit)
+
+        progress = Gtk.ProgressBar(show_text=True)
+        win.add(progress)
+
+        def update_progess(i):
+            progress.pulse()
+            progress.set_text(str(i))
+            return False
+
+        def example_target():
+            for i in range(50):
+                GLib.idle_add(update_progess, i)
+                time.sleep(0.2)
+
+        win.show_all()
+
+        thread = threading.Thread(target=example_target)
+        thread.daemon = True
+        thread.start()
+
+
+    if __name__ == "__main__":
+        app_main()
+        Gtk.main()
+
+
+The example shows a simple window containing a progress bar. After everything
+is set up it constructs a Python thread, passes it a function to execute,
+starts the thread and the GTK+ main loop. After the main loop is started it is
+possible to see the window and interact with it.
+
+In the background ``example_target()`` gets executed and calls
+:func:`GLib.idle_add` and :func:`time.sleep` in a loop. In this example
+:func:`time.sleep` represents the blocking operation. :func:`GLib.idle_add`
+takes the ``update_progess()`` function and arguments that will get passed to
+the function and asks the main loop to schedule its execution in the main
+thread. This is needed because GTK+ isn't thread safe; only one thread, the
+main thread, is allowed to call GTK+ code at all times.
+
+
+Threads: FAQ
+------------
+
+* I'm porting code from pygtk (GTK+ 2) to PyGObject (GTK+ 3). Has anything 
+  changed regarding threads?
+
+  Short answer: No.
+
+  Long answer: ``gtk.gdk.threads_init()``, ``gtk.gdk.threads_enter()`` and
+  ``gtk.gdk.threads_leave()`` are now :func:`Gdk.threads_init`,
+  :func:`Gdk.threads_enter` and :func:`Gdk.threads_leave`.
+  ``gobject.threads_init()`` can be removed.
+
+* I'm using :func:`Gdk.threads_init` and want to get rid of it. What do I 
+  need to do?
+
+  * Remove any :func:`Gdk.threads_init()`, :func:`Gdk.threads_enter` and  
+    :func:`Gdk.threads_leave` calls. In case they get executed in a thread,
+    move the GTK+ code into its own function and schedule it using
+    :func:`GLib.idle_add`. Be aware that the newly created function will be
+    executed some time later, so other stuff can happen in between.
+
+  * Replace any call to ``Gdk.threads_add_*()`` with their GLib counterpart.
+    For example :func:`GLib.idle_add` instead of :func:`Gdk.threads_add_idle`.
+
+* What about signals and threads?
+
+  Signals get executed in the context they are emitted from. In which context
+  the object is created or where ``connect()`` is called from doesn't matter.
+  In GStreamer, for example, some signals can be called from a different
+  thread, see the respective signal documentation for when this is the case.
+  In case you connect to such a signal you have to make sure to not call any
+  GTK+ code or use :func:`GLib.idle_add` accordingly.
+
+* What if I need to call GTK+ code in signal handlers emitted from a thread?
+
+  In case you have a signal that is emitted from another thread and you need
+  to call GTK+ code during and not after signal handling, you can push the
+  operation with an :class:`threading.Event` object to the main loop and wait
+  in the signal handler until the operation gets scheduled and the result is
+  available. Be aware that if the signal is emitted from the main loop this
+  will deadlock. See the following example
+
+  .. code:: python
+
+        # [...]
+
+        toggle_button = Gtk.ToggleButton()
+
+        def signal_handler_in_thread():
+
+            def function_calling_gtk(event, result):
+                result.append(toggle_button.get_active())
+                event.set()
+
+            event = threading.Event()
+            result = []
+            GLib.idle_add(function_calling_gtk, event, result)
+            event.wait()
+            toggle_button_is_active = result[0]
+            print(toggle_button_is_active)
+
+        # [...]
+
+* What about the Python `GIL
+  <https://en.wikipedia.org/wiki/Global_Interpreter_Lock>`__ ?
+
+  Similar to I/O operations in Python, all PyGObject calls release the 
+  GIL during their execution and other Python threads can be executed 
+  during that time.
+
+
+Asynchronous Operations
+-----------------------
+
+In addition to functions for blocking I/O glib also provides corresponding
+asynchronous versions, usually with the same name plus a ``_async`` suffix.
+These functions do the same operation as the synchronous ones but don't block
+during their execution. Instead of blocking they execute the operation in the
+background and call a callback once the operation is finished or got canceled.
+
+The following example shows how to download a web page and display the 
+source in a text field. In addition it's possible to abort the running 
+operation.
+
+
+.. code:: python
+
+    import time
+
+    from gi.repository import Gio, GLib, Gtk
+
+
+    class DownloadWindow(Gtk.Window):
+
+        def __init__(self):
+            super(DownloadWindow, self).__init__(
+                default_width=500, default_height=400, title="Async I/O Example")
+
+            self.cancellable = Gio.Cancellable()
+
+            self.cancel_button = Gtk.Button(label="Cancel")
+            self.cancel_button.connect("clicked", self.on_cancel_clicked)
+            self.cancel_button.set_sensitive(False)
+
+            self.start_button = Gtk.Button(label="Load")
+            self.start_button.connect("clicked", self.on_start_clicked)
+
+            textview = Gtk.TextView()
+            self.textbuffer = textview.get_buffer()
+            scrolled = Gtk.ScrolledWindow()
+            scrolled.add(textview)
+
+            box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6,
+                          border_width=12)
+            box.pack_start(self.start_button, False, True, 0)
+            box.pack_start(self.cancel_button, False, True, 0)
+            box.pack_start(scrolled, True, True, 0)
+
+            self.add(box)
+
+        def append_text(self, text):
+            iter_ = self.textbuffer.get_end_iter()
+            self.textbuffer.insert(iter_, "[%s] %s\n" % (str(time.time()), text))
+
+        def on_start_clicked(self, button):
+            button.set_sensitive(False)
+            self.cancel_button.set_sensitive(True)
+            self.append_text("Start clicked...")
+
+            file_ = Gio.File.new_for_uri(
+                "http://python-gtk-3-tutorial.readthedocs.org/")
+            file_.load_contents_async(
+                self.cancellable, self.on_ready_callback, None)
+
+        def on_cancel_clicked(self, button):
+            self.append_text("Cancel clicked...")
+            self.cancellable.cancel()
+
+        def on_ready_callback(self, source_object, result, user_data):
+            try:
+                succes, content, etag = source_object.load_contents_finish(result)
+            except GLib.GError as e:
+                self.append_text("Error: " + e.message)
+            else:
+                content_text = content[:100].decode("utf-8")
+                self.append_text("Got content: " + content_text + "...")
+            finally:
+                self.cancellable.reset()
+                self.cancel_button.set_sensitive(False)
+                self.start_button.set_sensitive(True)
+
+
+    if __name__ == "__main__":
+        win = DownloadWindow()
+        win.show_all()
+        win.connect("destroy", Gtk.main_quit)
+
+        Gtk.main()
+
+
+The example uses the asynchronous version of :meth:`Gio.File.load_contents` to
+load the content of an URI pointing to a web page, but first we look at the
+simpler blocking alternative:
+
+We create a :class:`Gio.File` instance for our URI and call
+:meth:`Gio.File.load_contents`, which, if it doesn't raise an error, returns
+the content of the web page we wanted.
+
+.. code:: python
+
+    file = Gio.File.new_for_uri("http://python-gtk-3-tutorial.readthedocs.org/")
+    try:
+        status, contents, etag_out = file.load_contents(None)
+    except GLib.GError:
+        print("Error!")
+    else:
+        print(contents)
+
+In the asynchronous variant we need two more things:
+
+* A :class:`Gio.Cancellable`, which we can use during the operation to 
+  abort or cancel it.
+* And a :func:`Gio.AsyncReadyCallback` callback function, which gets called
+  once the operation is finished and we can collect the result.
+
+The window contains two buttons for which we register ``clicked`` signal
+handlers:
+
+* The ``on_start_clicked()`` signal handler calls 
+  :meth:`Gio.File.load_contents_async` with a :class:`Gio.Cancellable` 
+  and ``on_ready_callback()`` as :func:`Gio.AsyncReadyCallback`.
+* The ``on_cancel_clicked()`` signal handler calls 
+  :meth:`Gio.Cancellable.cancel` to cancel the running operation.
+
+Once the operation is finished, either because the result is available, an
+error occurred or the operation was canceled, ``on_ready_callback()`` will be
+called with the :class:`Gio.File` instance and a :class:`Gio.AsyncResult`
+instance which holds the result.
+
+To get the result we now have to call :meth:`Gio.File.load_contents_finish` 
+which returns the same things as :meth:`Gio.File.load_contents` except in 
+this case the result is already there and it will return immediately 
+without blocking.
+
+After all this is done we call :meth:`Gio.Cancellable.reset` so the 
+:class:`Gio.Cancellable` can be re-used for new operations and we can click 
+the "Load" button again. This works since we made sure that only one 
+operation can be active at any time by deactivating the "Load" button using 
+:meth:`Gtk.Widget.set_sensitive`.
diff --git a/docs/icons.rst b/docs/icons.rst
new file mode 100644 (file)
index 0000000..7637df2
--- /dev/null
@@ -0,0 +1,48 @@
+.. |python-logo| raw:: html
+
+    <i class="icon-python"></i>
+
+
+.. |ubuntu-logo| raw:: html
+
+    <i class="icon-ubuntu"></i>
+
+.. |debian-logo| raw:: html
+
+    <i class="icon-debian"></i>
+
+.. |fedora-logo| raw:: html
+
+    <i class="icon-fedora"></i>
+
+.. |opensuse-logo| raw:: html
+
+    <i class="icon-suse"></i>
+
+.. |windows-logo| raw:: html
+
+    <i class="fa fa-windows"></i>
+
+.. |source-logo| raw:: html
+
+    <i class="fa fa-file"></i>
+
+.. |arch-logo| raw:: html
+
+    <i class="icon-archlinux"></i>
+
+.. |macosx-logo| raw:: html
+
+    <i class="fa fa-apple"></i>
+
+.. |github-logo| raw:: html
+
+    <i class="fa fa-github"></i>
+
+.. |bug-logo| raw:: html
+
+    <i class="fa fa-bug"></i>
+
+.. |linux-logo| raw:: html
+
+    <i class="fa fa-linux"></i>
diff --git a/docs/images/LICENSE b/docs/images/LICENSE
new file mode 100644 (file)
index 0000000..0fbbdbf
--- /dev/null
@@ -0,0 +1,3 @@
+pygobject.svg and pygobject-small.svg are based on the GTK+ logo, created by
+Andreas Nilsson, licensed under CC BY-SA 3.0. For more info see
+https://commons.wikimedia.org/wiki/File:GTK%2B_logo.svg
diff --git a/docs/images/favicon.ico b/docs/images/favicon.ico
new file mode 100644 (file)
index 0000000..905b200
Binary files /dev/null and b/docs/images/favicon.ico differ
diff --git a/docs/images/logo.svg b/docs/images/logo.svg
new file mode 100644 (file)
index 0000000..3f4ebde
--- /dev/null
@@ -0,0 +1,266 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="135"
+   height="135"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.91 r13725"
+   version="1.0"
+   sodipodi:docname="logo.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs4">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective10" />
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2897" />
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       id="perspective2450" />
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2474">
+      <path
+         d="m 0,450.7086 121.89,0 0,153.071 -121.89,0 0,-153.071 z"
+         id="path2476"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2484">
+      <path
+         d="m 1701.323,36.99957 283.465,0 0,595.276 -283.465,0 0,-595.276 z"
+         id="path2486"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2494">
+      <path
+         d="m 0,1802.8342 487.5601,0 0,578.1658 L 0,2381 0,1802.8342 z"
+         id="path2496"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2504">
+      <path
+         d="m -1.5e-6,-2.94433 2.3255315,0 0,3.88873 -2.3255315,0 0,-3.88873 z"
+         id="path2506"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2514">
+      <path
+         d="m 0,1802.8342 487.5601,0 0,578.1658 L 0,2381 0,1802.8342 z"
+         id="path2516"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2532">
+      <path
+         d="m 9.806,537.3086 104.874,0 0,28.203 -104.874,0 0,-28.203 z"
+         id="path2534"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2542">
+      <path
+         d="m 1701.323,36.99957 283.465,0 0,595.276 -283.465,0 0,-595.276 z"
+         id="path2544"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2552">
+      <path
+         d="m 39.2241,2149.2344 419.4961,0 0,112.812 -419.4961,0 0,-112.812 z"
+         id="path2554"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2562">
+      <path
+         d="m -0.0935124,-19.05134 2.7028824,0 0,21.10663 -2.7028824,0 0,-21.10663 z"
+         id="path2564"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2572">
+      <path
+         d="m 39.2241,2149.2344 419.4961,0 0,112.812 -419.4961,0 0,-112.812 z"
+         id="path2574"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2612">
+      <path
+         d="m 0,-9.1245 291.968,0 0,462.668 -291.968,0 0,-462.668 z"
+         id="path2614"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2618">
+      <path
+         d="m 0,0 283.5,0 0,453.5436 -283.5,0 L 0,0 z"
+         id="path2620"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2628">
+      <path
+         d="m 1701.323,36.99957 283.465,0 0,595.276 -283.465,0 0,-595.276 z"
+         id="path2630"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2638">
+      <path
+         d="m 0,0 1134,0 0,1814.1743 -1134,0 L 0,0 z"
+         id="path2640"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2644">
+      <path
+         d="m 0,0 1134,0 0,1814.1743 -1134,0 L 0,0 z"
+         id="path2646"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2654">
+      <path
+         d="m 8.716e-4,0.0203769 0.9688584,0 0,1.2848631 -0.9688584,0 0,-1.2848631 z"
+         id="path2656"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <clipPath
+       clipPathUnits="userSpaceOnUse"
+       id="clipPath2664">
+      <path
+         d="m 0,0 1134,0 0,1814.1743 -1134,0 L 0,0 z"
+         id="path2666"
+         inkscape:connector-curvature="0" />
+    </clipPath>
+    <inkscape:perspective
+       id="perspective2777"
+       inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+       inkscape:vp_z="744.09448 : 526.18109 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 526.18109 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <filter
+       inkscape:collect="always"
+       style="color-interpolation-filters:sRGB"
+       id="filter4210"
+       x="-0.013603581"
+       width="1.0272072"
+       y="-0.010734612"
+       height="1.0214692">
+      <feGaussianBlur
+         inkscape:collect="always"
+         stdDeviation="0.17314453"
+         id="feGaussianBlur4212" />
+    </filter>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.979899"
+     inkscape:cx="18.317077"
+     inkscape:cy="97.877634"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1280"
+     inkscape:window-height="674"
+     inkscape:window-x="0"
+     inkscape:window-y="26"
+     inkscape:window-maximized="0"
+     showborder="true"
+     fit-margin-top="9"
+     fit-margin-left="9"
+     fit-margin-right="9"
+     fit-margin-bottom="9" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Ebene 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-74.24472,-374.35257)">
+    <rect
+       style="fill:#000000;fill-opacity:1"
+       id="rect3079"
+       width="117"
+       height="117"
+       x="83.24472"
+       y="383.35257"
+       ry="23.031063" />
+    <g
+       id="g3855"
+       transform="translate(0.7466894,0.04879762)"
+       style="fill:#4e9a06" />
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter4210)"
+       x="106.41864"
+       y="461.19006"
+       id="text4178"
+       sodipodi:linespacing="125%"
+       transform="matrix(1.1069586,0,0,1.1069586,-15.44004,-48.180085)"><tspan
+         sodipodi:role="line"
+         id="tspan4180"
+         x="106.41864"
+         y="461.19006"
+         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:87.5px;font-family:Cantarell;-inkscape-font-specification:'Cantarell Bold';text-align:start;text-anchor:start;opacity:1;fill:#ffffff;fill-opacity:1">gi</tspan></text>
+  </g>
+</svg>
diff --git a/docs/images/overview.dia b/docs/images/overview.dia
new file mode 100644 (file)
index 0000000..08b0243
Binary files /dev/null and b/docs/images/overview.dia differ
diff --git a/docs/images/overview.svg b/docs/images/overview.svg
new file mode 100644 (file)
index 0000000..37d6e2c
--- /dev/null
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
+<svg width="27cm" height="10cm" viewBox="220 135 524 199" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <defs/>
+  <g id="Background">
+    <rect style="fill: #ffffff; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke-linejoin: round; stroke: #646464" x="456.332" y="136.698" width="134.923" height="196.302" rx="8" ry="8"/>
+    <g>
+      <rect style="fill: #ffffff; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke-linejoin: round; stroke: #5a9fd4" x="221.09" y="214.954" width="80" height="36" rx="10" ry="10"/>
+      <text font-size="12.8" style="fill: #646464; fill-opacity: 1; stroke: none;text-anchor:middle;font-family:Lato;font-style:normal;font-weight:500" x="261.09" y="237.604">
+        <tspan x="261.09" y="237.604">Python</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: #ffffff; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke-linejoin: round; stroke: #5a9fd4" x="338" y="216.562" width="81.6" height="36" rx="10" ry="10"/>
+      <text font-size="12.8" style="fill: #646464; fill-opacity: 1; stroke: none;text-anchor:middle;font-family:Lato;font-style:normal;font-weight:500" x="378.8" y="239.212">
+        <tspan x="378.8" y="239.212">PyGObject</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: #ffffff; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke-linejoin: round; stroke: #5a9fd4" x="473.126" y="147.249" width="100.6" height="36" rx="10" ry="10"/>
+      <text font-size="12.8" style="fill: #646464; fill-opacity: 1; stroke: none;text-anchor:middle;font-family:Lato;font-style:normal;font-weight:500" x="523.426" y="169.899">
+        <tspan x="523.426" y="169.899">libgirepository</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: #ffffff; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke-linejoin: round; stroke: #5a9fd4" x="483.752" y="192.25" width="80" height="36" rx="10" ry="10"/>
+      <text font-size="12.8" style="fill: #646464; fill-opacity: 1; stroke: none;text-anchor:middle;font-family:Lato;font-style:normal;font-weight:500" x="523.752" y="214.9">
+        <tspan x="523.752" y="214.9">libglib</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: #ffffff; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke-linejoin: round; stroke: #5a9fd4" x="483.834" y="238.25" width="80" height="36" rx="10" ry="10"/>
+      <text font-size="12.8" style="fill: #646464; fill-opacity: 1; stroke: none;text-anchor:middle;font-family:Lato;font-style:normal;font-weight:500" x="523.834" y="260.9">
+        <tspan x="523.834" y="260.9">libgobject</tspan>
+      </text>
+    </g>
+    <g>
+      <line style="fill: none; stroke-opacity: 1; stroke-width: 2; stroke-linejoin: round; stroke: #646464" x1="301.09" y1="232.954" x2="330.289" y2="233.558"/>
+      <polygon style="fill: #646464; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke: #646464" fill-rule="evenodd" points="334.788,233.651 328.727,236.527 330.289,233.558 328.851,230.528 "/>
+    </g>
+    <g>
+      <line style="fill: none; stroke-opacity: 1; stroke-width: 2; stroke: #646464" x1="419.6" y1="234.562" x2="449.596" y2="234.796"/>
+      <polygon style="fill: #646464; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke: #646464" fill-rule="evenodd" points="454.096,234.831 448.073,237.784 449.596,234.796 448.12,231.784 "/>
+    </g>
+    <g>
+      <path style="fill: none; stroke-opacity: 1; stroke-width: 2; stroke: #646464" d="M 591.256 234.848 C 615.096,234.848 615.096,200.938 632.302,200.938"/>
+      <polygon style="fill: #646464; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke: #646464" fill-rule="evenodd" points="636.802,200.938 630.802,203.938 632.302,200.938 630.802,197.938 "/>
+    </g>
+    <g>
+      <path style="fill: none; stroke-opacity: 1; stroke-width: 2; stroke: #646464" d="M 591.256 234.848 C 615.096,234.848 615.096,270.234 631.594,270.234"/>
+      <polygon style="fill: #646464; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke: #646464" fill-rule="evenodd" points="636.094,270.234 630.094,273.234 631.594,270.234 630.094,267.234 "/>
+    </g>
+    <g>
+      <rect style="fill: #ffffff; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke: #5a9fd4" x="484" y="285.9" width="80" height="36" rx="10" ry="10"/>
+      <text font-size="12.8" style="fill: #646464; fill-opacity: 1; stroke: none;text-anchor:middle;font-family:Lato;font-style:normal;font-weight:500" x="524" y="308.55">
+        <tspan x="524" y="308.55">libffi</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: #ffffff; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke: #5a9fd4" x="639.038" y="182.938" width="104.05" height="36" rx="10" ry="10"/>
+      <text font-size="12.8" style="fill: #646464; fill-opacity: 1; stroke: none;text-anchor:middle;font-family:Lato;font-style:normal;font-weight:500" x="691.063" y="205.588">
+        <tspan x="691.063" y="205.588">Gtk-3.0.typelib</tspan>
+      </text>
+    </g>
+    <g>
+      <rect style="fill: #ffffff; fill-opacity: 1; stroke-opacity: 1; stroke-width: 2; stroke: #5a9fd4" x="638.33" y="252.234" width="80" height="36" rx="10" ry="10"/>
+      <text font-size="12.8" style="fill: #646464; fill-opacity: 1; stroke: none;text-anchor:middle;font-family:Lato;font-style:normal;font-weight:500" x="678.33" y="274.884">
+        <tspan x="678.33" y="274.884">libgtk-3.so</tspan>
+      </text>
+    </g>
+  </g>
+</svg>
diff --git a/docs/images/pygobject-small.svg b/docs/images/pygobject-small.svg
new file mode 100644 (file)
index 0000000..e6576e8
--- /dev/null
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="88.572403"
+   height="96.050858"
+   id="svg6843"
+   sodipodi:docname="pygobject-small.svg"
+   inkscape:version="0.92.1 r15371">
+  <metadata
+     id="metadata12">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="674"
+     id="namedview10"
+     showgrid="false"
+     inkscape:zoom="1.2285173"
+     inkscape:cx="135.96584"
+     inkscape:cy="-1.8615718"
+     inkscape:window-x="0"
+     inkscape:window-y="26"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="layer1" />
+  <defs
+     id="defs6845">
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4534">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4530" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4532" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4522">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4518" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4520" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4660">
+      <stop
+         style="stop-color:#646464;stop-opacity:1;"
+         offset="0"
+         id="stop4656" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="1"
+         id="stop4658" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4652">
+      <stop
+         style="stop-color:#5a9fd4;stop-opacity:1;"
+         offset="0"
+         id="stop4648" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.94650203"
+         offset="1"
+         id="stop4650" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4644">
+      <stop
+         style="stop-color:#edd400;stop-opacity:1;"
+         offset="0"
+         id="stop4640" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="1"
+         id="stop4642" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4644"
+       id="linearGradient4646"
+       x1="53.816978"
+       y1="111.10486"
+       x2="20.88413"
+       y2="30.82696"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4652"
+       id="linearGradient4654"
+       x1="70.43454"
+       y1="17.875593"
+       x2="53.816978"
+       y2="111.10486"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4660"
+       id="linearGradient4662"
+       x1="23.216625"
+       y1="81.319481"
+       x2="107.33282"
+       y2="39.060543"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4522"
+       id="linearGradient4524"
+       x1="70.587303"
+       y1="17.177763"
+       x2="70.485733"
+       y2="67.361443"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4534"
+       id="linearGradient4536"
+       x1="69.029457"
+       y1="87.363297"
+       x2="70.373047"
+       y2="68.046875"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <g
+     transform="translate(-19.822261,-15.90723)"
+     id="layer1">
+    <g
+       id="g4527"
+       transform="translate(0,-0.20854102)">
+      <path
+         inkscape:connector-curvature="0"
+         style="display:inline;opacity:1;fill:url(#linearGradient4654);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12400007;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         id="path6976"
+         d="M 20.88413,30.82696 53.816977,55.527708 107.33282,39.060543 70.587303,17.177763 Z" />
+      <path
+         inkscape:connector-curvature="0"
+         style="display:inline;fill:url(#linearGradient4662);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12364459;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         id="path6978"
+         d="M 22.94243,82.287118 20.88413,30.82696 53.816977,55.527708 v 55.577152 z" />
+      <path
+         inkscape:connector-curvature="0"
+         style="display:inline;opacity:1;fill:url(#linearGradient4646);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12364459;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         id="path6980"
+         d="M 53.816977,111.10486 103.21619,90.5207 107.33282,39.060543 53.816977,55.527708 Z" />
+      <path
+         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:url(#linearGradient4536);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 70.597656,66.675781 -47.558594,14.044922 0.355469,1.197266 46.978516,-13.871094 32.652343,22.910156 0.71875,-1.023437 z"
+         id="path6982"
+         inkscape:connector-curvature="0" />
+      <path
+         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:url(#linearGradient4524);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 69.808594,17.875 v 49.109375 h 1.25 V 17.875 Z"
+         id="path6984"
+         inkscape:connector-curvature="0" />
+    </g>
+  </g>
+</svg>
diff --git a/docs/images/pygobject.svg b/docs/images/pygobject.svg
new file mode 100644 (file)
index 0000000..fbf88e1
--- /dev/null
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.0"
+   width="392.86777"
+   height="96.050858"
+   id="svg6843"
+   sodipodi:docname="pygobject.svg"
+   inkscape:version="0.92.1 r15371">
+  <metadata
+     id="metadata12">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1366"
+     inkscape:window-height="674"
+     id="namedview10"
+     showgrid="false"
+     inkscape:zoom="1.2285173"
+     inkscape:cx="135.96584"
+     inkscape:cy="-1.8615724"
+     inkscape:window-x="0"
+     inkscape:window-y="26"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="g4527" />
+  <defs
+     id="defs6845">
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4534">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4530" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4532" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4522">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop4518" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop4520" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4660">
+      <stop
+         style="stop-color:#646464;stop-opacity:1;"
+         offset="0"
+         id="stop4656" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="1"
+         id="stop4658" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4652">
+      <stop
+         style="stop-color:#5a9fd4;stop-opacity:1;"
+         offset="0"
+         id="stop4648" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0.94650203"
+         offset="1"
+         id="stop4650" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient4644">
+      <stop
+         style="stop-color:#edd400;stop-opacity:1;"
+         offset="0"
+         id="stop4640" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="1"
+         id="stop4642" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4644"
+       id="linearGradient4646"
+       x1="53.816978"
+       y1="111.10486"
+       x2="20.88413"
+       y2="30.82696"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4652"
+       id="linearGradient4654"
+       x1="70.43454"
+       y1="17.875593"
+       x2="53.816978"
+       y2="111.10486"
+       gradientUnits="userSpaceOnUse"
+       spreadMethod="pad" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4660"
+       id="linearGradient4662"
+       x1="23.216625"
+       y1="81.319481"
+       x2="107.33282"
+       y2="39.060543"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4522"
+       id="linearGradient4524"
+       x1="70.587303"
+       y1="17.177763"
+       x2="70.485733"
+       y2="67.361443"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient4534"
+       id="linearGradient4536"
+       x1="69.029457"
+       y1="87.363297"
+       x2="70.373047"
+       y2="68.046875"
+       gradientUnits="userSpaceOnUse" />
+  </defs>
+  <g
+     transform="translate(-19.822261,-15.90723)"
+     id="layer1">
+    <g
+       id="g4527"
+       transform="translate(0,-0.20854102)">
+      <path
+         inkscape:connector-curvature="0"
+         style="display:inline;opacity:1;fill:url(#linearGradient4654);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12400007;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         id="path6976"
+         d="M 20.88413,30.82696 53.816977,55.527708 107.33282,39.060543 70.587303,17.177763 Z" />
+      <path
+         inkscape:connector-curvature="0"
+         style="display:inline;fill:url(#linearGradient4662);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12364459;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         id="path6978"
+         d="M 22.94243,82.287118 20.88413,30.82696 53.816977,55.527708 v 55.577152 z" />
+      <path
+         inkscape:connector-curvature="0"
+         style="display:inline;opacity:1;fill:url(#linearGradient4646);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.12364459;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         id="path6980"
+         d="M 53.816977,111.10486 103.21619,90.5207 107.33282,39.060543 53.816977,55.527708 Z" />
+      <path
+         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:url(#linearGradient4536);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 70.597656,66.675781 -47.558594,14.044922 0.355469,1.197266 46.978516,-13.871094 32.652343,22.910156 0.71875,-1.023437 z"
+         id="path6982"
+         inkscape:connector-curvature="0" />
+      <path
+         style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:url(#linearGradient4524);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+         d="m 69.808594,17.875 v 49.109375 h 1.25 V 17.875 Z"
+         id="path6984"
+         inkscape:connector-curvature="0" />
+    </g>
+    <g
+       aria-label="PyGObject"
+       style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:25px;font-family:Cantarell;-inkscape-font-specification:Cantarell;letter-spacing:-2px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       id="text4518"
+       transform="matrix(0.73060434,0,0,0.73060434,39.415227,17.281548)">
+      <path
+         d="m 134.29489,66.572751 c 14.8,0 26.88,-2.96 26.88,-17.44 0,-10.96 -7.68,-16.4 -22.96,-16.4 h -18.32 v 55.36 h 9.84 v -21.52 z m 16.8,-17.04 c 0,7.44 -7.76,8 -16.4,8 h -4.96 v -15.76 h 7.44 c 7.36,0 13.92,0.96 13.92,7.76 z"
+         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:80px;font-family:Cantarell;-inkscape-font-specification:'Cantarell Bold';letter-spacing:0px;word-spacing:0px;fill:#646464;fill-opacity:1"
+         id="path4529"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 164.91864,49.612751 17.44,38.8 -8.8,20.399999 h 10.8 l 23.6,-59.199999 h -10.16 l -10.4,29.52 -11.44,-29.52 z"
+         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:80px;font-family:Cantarell;-inkscape-font-specification:'Cantarell Bold';letter-spacing:0px;word-spacing:0px;fill:#646464;fill-opacity:1"
+         id="path4531"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 211.70114,60.092751 c 0,18.64 11.12,28.8 27.68,28.8 9.68,0 17.04,-2.4 22.4,-6.64 v -25.44 h -24.4 v 9.04 h 14.56 v 11.68 c -3.28,1.6 -5.84,2.32 -10.96,2.32 -11.28,0 -19.44,-6.48 -19.44,-20.16 0,-12.96 6.08,-19.04 19.68,-19.04 6.4,0 12,2.24 16.24,4.4 l 2.72,-8.72 c -5.28,-3.2 -12.48,-4.72 -19.2,-4.72 -19.52,0 -29.28,11.36 -29.28,28.48 z"
+         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:80px;font-family:Cantarell;-inkscape-font-specification:'Cantarell Bold';letter-spacing:0px;word-spacing:0px;fill:#646464;fill-opacity:1"
+         id="path4533"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 297.97114,31.612751 c -16.48,0 -27.52,11.92 -27.52,28.64 0,16.8 10.88,28.64 27.2,28.64 16.8,0 27.84,-12.24 27.84,-29.2 0,-16.64 -11.04,-28.08 -27.52,-28.08 z m -0.4,9.04 c 11.12,0 18.08,8.08 18.08,19.6 0,11.52 -6.24,19.6 -17.36,19.6 -11.2,0 -18,-8.72 -18,-20.24 0,-11.28 6.32,-18.96 17.28,-18.96 z"
+         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:80px;font-family:Cantarell;-inkscape-font-specification:'Cantarell Bold';letter-spacing:0px;word-spacing:0px;fill:#646464;fill-opacity:1"
+         id="path4535"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 340.09739,88.092751 1.92,-2.48 c 3.84,2.24 7.68,3.28 11.6,3.28 11.52,0 18.32,-8.56 18.32,-20.24 0,-11.68 -4.72,-19.92 -16.56,-19.92 -4.56,0 -8.32,1.12 -11.6,2.8 v -20.88 h -9.84 v 57.44 z m 3.68,-29.2 c 1.92,-0.8 5.68,-2.16 9.2,-2.16 6.88,0 9.12,4.96 9.12,12.48 0,7.52 -3.52,11.92 -10.08,11.92 -3.2,0 -5.92,-0.8 -8.24,-2.64 z"
+         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:80px;font-family:Cantarell;-inkscape-font-specification:'Cantarell Bold';letter-spacing:0px;word-spacing:0px;fill:#646464;fill-opacity:1"
+         id="path4537"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 385.06739,44.972751 c 3.12,0 5.92,-2.8 5.92,-5.92 0,-3.12 -2.8,-5.92 -5.92,-5.92 -3.12,0 -5.92,2.8 -5.92,5.92 0,3.12 2.8,5.92 5.92,5.92 z m -8.48,56.319999 c -1.2,0 -2.24,-0.24 -2.24,-0.24 l -1.92,7.36 c 0,0 2.64,0.8 5.44,0.8 10.16,0 12.24,-6.96 12.24,-13.999999 v -45.6 h -9.84 v 43.6 c 0,4.96 -0.56,8.079999 -3.68,8.079999 z"
+         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:80px;font-family:Cantarell;-inkscape-font-specification:'Cantarell Bold';letter-spacing:0px;word-spacing:0px;fill:#646464;fill-opacity:1"
+         id="path4539"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 420.17989,81.132751 c -9.44,0 -11.6,-4.08 -12,-9.04 h 26.4 v -3.76 c 0,-12.56 -5.92,-19.6 -17.44,-19.6 -11.44,0 -18.88,8.96 -18.88,20.08 0,12.48 7.68,20.08 20.64,20.08 5.12,0 10.08,-0.88 14.8,-2.4 l -1.92,-7.36 c -3.52,1.36 -7.36,2 -11.6,2 z m -11.92,-15.84 c 0.48,-4.64 2.48,-8.96 9.04,-8.96 4.8,0 7.44,2.8 7.44,8.96 z"
+         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:80px;font-family:Cantarell;-inkscape-font-specification:'Cantarell Bold';letter-spacing:0px;word-spacing:0px;fill:#646464;fill-opacity:1"
+         id="path4541"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 450.44364,68.812751 c 0,-7.44 4.4,-12.4 12.8,-12.4 5.04,0 7.84,1.2 9.6,2.16 l 1.92,-7.36 c -1.92,-1.2 -5.44,-2.48 -12.56,-2.48 -13.2,0 -21.6,7.76 -21.6,20.08 0,12 8.72,20.08 21.92,20.08 6.08,0 11.04,-1.76 12.4,-2.4 l -1.92,-7.36 c -1.68,0.8 -4.72,2.08 -9.76,2.08 -7.92,0 -12.8,-5.12 -12.8,-12.4 z"
+         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:80px;font-family:Cantarell;-inkscape-font-specification:'Cantarell Bold';letter-spacing:0px;word-spacing:0px;fill:#646464;fill-opacity:1"
+         id="path4543"
+         inkscape:connector-curvature="0" />
+      <path
+         d="m 510.91239,86.732751 -1.44,-6.8 c -1.44,0.4 -4.4,1.12 -7.12,1.12 -5.28,0 -6.48,-2.64 -6.48,-5.6 v -18.16 h 13.28 v -7.68 h -13.28 v -12.08 h -9.84 v 12.08 h -6.4 v 7.68 h 6.4 v 18.4 c 0,6.8 1.68,13.2 13.92,13.2 3.68,0 8.24,-1.12 10.96,-2.16 z"
+         style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:80px;font-family:Cantarell;-inkscape-font-specification:'Cantarell Bold';letter-spacing:0px;word-spacing:0px;fill:#646464;fill-opacity:1"
+         id="path4545"
+         inkscape:connector-curvature="0" />
+    </g>
+  </g>
+</svg>
diff --git a/docs/images/start_linux.png b/docs/images/start_linux.png
new file mode 100644 (file)
index 0000000..5a557ee
Binary files /dev/null and b/docs/images/start_linux.png differ
diff --git a/docs/images/start_macos.png b/docs/images/start_macos.png
new file mode 100644 (file)
index 0000000..8b35a95
Binary files /dev/null and b/docs/images/start_macos.png differ
diff --git a/docs/images/start_windows.png b/docs/images/start_windows.png
new file mode 100644 (file)
index 0000000..db4ce32
Binary files /dev/null and b/docs/images/start_windows.png differ
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644 (file)
index 0000000..82e76a9
--- /dev/null
@@ -0,0 +1,89 @@
+.. include:: icons.rst
+
+.. title:: Overview
+
+.. toctree::
+    :hidden:
+    :titlesonly:
+    :maxdepth: 1
+
+    getting_started
+    changelog
+    guide/index
+    devguide/index
+    packagingguide
+    maintguide
+    further
+    contact
+
+.. image:: images/pygobject.svg
+   :align: center
+   :width: 400px
+   :height: 98px
+
+|
+
+.. include:: ../README.rst
+    :start-after: |
+    :end-before: ----
+
+If you want to write a Python application for `GNOME
+<https://www.gnome.org/>`__ or a Python GUI application using GTK+, then
+PyGObject is the way to go. For more information on specific libraries check
+out the "`Python GTK+ 3 Tutorial
+<https://python-gtk-3-tutorial.readthedocs.io>`__" and the "`Python GI API
+Reference <https://lazka.github.io/pgi-docs>`__".
+
+.. code:: python
+
+    import gi
+    gi.require_version("Gtk", "3.0")
+    from gi.repository import Gtk
+
+    window = Gtk.Window(title="Hello World")
+    window.show()
+    window.connect("destroy", Gtk.main_quit)
+    Gtk.main()
+
+
+How does it work?
+-----------------
+
+.. figure:: images/overview.svg
+    :width: 600px
+    :height: 222px
+    :align: center
+
+PyGObject uses `glib <https://developer.gnome.org/glib/stable/>`__, `gobject
+<https://developer.gnome.org/gobject/stable/>`__, `girepository
+<https://developer.gnome.org/gi/stable/>`__, `libffi
+<https://sourceware.org/libffi/>`__ and other libraries to access the C
+library (libgtk-3.so) in combination with the additional metadata from the
+accompanying typelib file (Gtk-3.0.typelib) and dynamically provides a Python
+interface based on that information.
+
+
+Who Is Using PyGObject?
+-----------------------
+
+* `D-Feet <https://wiki.gnome.org/action/show/Apps/DFeet>`__ - an easy to use D-Bus debugger
+* `GNOME Music <https://wiki.gnome.org/Apps/Music>`__ - a music player for GNOME
+* `GNOME Tweak Tool <https://wiki.gnome.org/action/show/Apps/GnomeTweakTool>`__ - a tool to customize advanced GNOME 3 options
+* `Gramps <https://gramps-project.org/>`__ - a genealogy program
+* `Lollypop <https://gnumdk.github.io/lollypop-web/>`__ - a modern music player
+* `Meld <http://meldmerge.org/>`__ - a visual diff and merge tool
+* `MyPaint <http://mypaint.org/>`__ - a nimble, distraction-free, and easy tool for digital painters
+* `Orca <https://wiki.gnome.org/Projects/Orca>`__ - a flexible and extensible screen reader
+* `Pithos <https://pithos.github.io/>`__ - a Pandora Radio client
+* `Pitivi <http://www.pitivi.org/>`__ - a free and open source video editor
+* `Quod Libet <https://quodlibet.readthedocs.io/>`__ - a music library manager / player
+* `Transmageddon <http://www.linuxrising.org/>`__ - a video transcoder
+
+
+The following applications or libraries use PyGObject for optional features,
+such as plugins or as optional backends:
+
+* `beets <http://beets.io/>`__ - a music library manager and MusicBrainz tagger
+* `gedit <https://wiki.gnome.org/Apps/Gedit>`_- a GNOME text editor
+* `matplotlib <http://matplotlib.org/>`__ - a python 2D plotting library
+* `Totem <https://wiki.gnome.org/Apps/Videos>`__ - a video player for GNOME
diff --git a/docs/maintguide.rst b/docs/maintguide.rst
new file mode 100644 (file)
index 0000000..c9cec1b
--- /dev/null
@@ -0,0 +1,32 @@
+================
+Maintainer Guide
+================
+
+Making a Release
+----------------
+
+#. Make sure configure.ac has the right version number
+#. Update NEWS file (use ``make release-news`` target and then edit as you see
+   fit)
+#. Run ``make distcheck``, fix any issues and commit.
+#. Commit NEWS as ``"release 3.X.Y"`` and push
+#. Tag with: ``git tag -s 3.X.Y -m "release 3.X.Y"``
+#. Push tag with: ``git push origin 3.X.Y``
+#. Commit post-release version bump to configure.ac
+#. Upload tarball: ``scp pygobject-3.X.Y.tar.gz user@master.gnome.org:``
+#. Install tarball:
+   ``ssh user@master.gnome.org 'ftpadmin install pygobject-3.X.Y.tar.gz'``
+
+Based on https://wiki.gnome.org/MaintainersCorner/Releasing
+
+
+Branching
+---------
+
+Each cycle after the feature freeze, we create a stable branch so development
+can continue in the master branch unaffected by the freezes.
+
+#. Create the branch locally with: ``git checkout -b pygobject-3-2``
+#. Push new branch: ``git push origin pygobject-3-2``
+#. In master, update configure.ac to what will be the next version number
+   (3.3.0)
diff --git a/docs/packagingguide.rst b/docs/packagingguide.rst
new file mode 100644 (file)
index 0000000..ab1fffe
--- /dev/null
@@ -0,0 +1,55 @@
+Packaging Guide
+===============
+
+Some notes on how to package PyGObject
+
+Source packages can be found at
+https://ftp.gnome.org/pub/GNOME/sources/pygobject
+
+
+Existing Packages:
+
+* https://www.archlinux.org/packages/extra/x86_64/python-gobject
+* https://packages.qa.debian.org/p/pygobject.html
+* https://github.com/Alexpux/MINGW-packages/tree/master/mingw-w64-pygobject
+
+
+Building::
+
+    ./configure --with-python=${PYTHON} --prefix="${PREFIX}"
+    make check # if you want to run the test suite
+    make DESTDIR="${PKGDIR}" install
+
+Runtime dependencies:
+
+    * glib
+    * libgirepository (gobject-introspection)
+    * libffi
+    * Python 2 or 3
+
+    The overrides directory contains various files which includes various
+    Python imports mentioning gtk, gdk etc. They are only used when the
+    corresponding library is present, they are not direct dependencies.
+
+Build dependencies:
+
+    * The runtime dependencies
+    * cairo (optional)
+    * pycairo (optional)
+    * pkg-config
+
+    If autotools is used:
+
+        * gnome-common for PyGObject < 3.26
+        * autoconf-archive for PyGObject >= 3.26
+
+    If setup.py is used:
+
+        * setuptools
+
+Test Suite dependencies:
+
+    * The runtime dependencies
+    * GTK+ 3 (optional)
+    * pango (optional)
+    * pycairo (optional)
index af3aa5c..95669db 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -29,8 +29,10 @@ import sys
 import errno
 import subprocess
 import tarfile
+import sysconfig
 from email import parser
 
+import pkg_resources
 from setuptools import setup, find_packages
 from distutils.core import Extension, Distribution
 from distutils.ccompiler import new_compiler
@@ -107,16 +109,8 @@ def parse_pkg_info(conf_dir):
 def _run_pkg_config(args):
     command = ["pkg-config"] + args
 
-    # Add $prefix/share/pkgconfig to PKG_CONFIG_PATH so we use the right
-    # pycairo in case we are in a virtualenv
-    env = dict(os.environ)
-    paths = env.get("PKG_CONFIG_PATH", "").split(os.pathsep)
-    paths = [p for p in paths if p]
-    paths.insert(0, os.path.join(sys.prefix, "share", "pkgconfig"))
-    env["PKG_CONFIG_PATH"] = os.pathsep.join(paths)
-
     try:
-        return subprocess.check_output(command, env=env)
+        return subprocess.check_output(command)
     except OSError as e:
         if e.errno == errno.ENOENT:
             raise SystemExit(
@@ -141,6 +135,19 @@ def pkg_config_parse(opt, pkg):
     return [x.lstrip(opt) for x in output.split()]
 
 
+def samefile(src, dst):
+    # Python 2 on Windows doesn't have os.path.samefile, so we have to provide
+    # a fallback
+
+    if hasattr(os.path, "samefile"):
+        return os.path.samefile(src, dst)
+
+    os.stat(src)
+    os.stat(dst)
+    return (os.path.normcase(os.path.abspath(src)) ==
+            os.path.normcase(os.path.abspath(dst)))
+
+
 du_sdist = get_command_class("sdist")
 
 
@@ -180,7 +187,8 @@ class distcheck(du_sdist):
         # make sure the tarball builds
         assert self.get_archive_files()
 
-        distcheck_dir = os.path.join(self.dist_dir, "distcheck")
+        distcheck_dir = os.path.abspath(
+            os.path.join(self.dist_dir, "distcheck"))
         if os.path.exists(distcheck_dir):
             dir_util.remove_tree(distcheck_dir)
         self.mkpath(distcheck_dir)
@@ -198,7 +206,11 @@ class distcheck(du_sdist):
         try:
             self.spawn([sys.executable, "setup.py", "build"])
             self.spawn([sys.executable, "setup.py", "install",
-                        "--root", "../prefix", "--record", "../log.txt"])
+                        "--root",
+                        os.path.join(distcheck_dir, "prefix"),
+                        "--record",
+                        os.path.join(distcheck_dir, "log.txt"),
+                        ])
         finally:
             os.chdir(old_pwd)
 
@@ -248,7 +260,6 @@ class build_ext(du_build_ext):
             "gio-2.0": ["gio-2.0", "gobject-2.0", "glib-2.0"],
             "gobject-introspection-1.0":
                 ["girepository-1.0", "gobject-2.0", "glib-2.0"],
-            get_pycairo_pkg_config_name(): ["cairo"],
             "cairo": ["cairo"],
             "cairo-gobject":
                 ["cairo-gobject", "cairo", "gobject-2.0", "glib-2.0"],
@@ -261,12 +272,6 @@ class build_ext(du_build_ext):
             if self.compiler_type == "msvc":
                 # assume that INCLUDE and LIB contains the right paths
                 ext.libraries += fallback_libs
-
-                # The PyCairo header is installed in a subdir of the
-                # Python installation that we are building for, so
-                # deduce that include path here, and use it
-                ext.include_dirs += [
-                    os.path.join(sys.prefix, "include", "pycairo")]
             else:
                 min_version = get_version_requirement(script_dir, name)
                 pkg_config_version_check(name, min_version)
@@ -274,6 +279,29 @@ class build_ext(du_build_ext):
                 ext.library_dirs += pkg_config_parse("--libs-only-L", name)
                 ext.libraries += pkg_config_parse("--libs-only-l", name)
 
+        def add_pycairo(ext):
+            min_version = get_version_requirement(
+                script_dir, get_pycairo_pkg_config_name())
+
+            dist = pkg_resources.get_distribution("pycairo>=%s" % min_version)
+
+            def get_sys_path(dist, name):
+                """The sysconfig path for a distribution, or None"""
+
+                location = dist.location
+                for scheme in sysconfig.get_scheme_names():
+                    for path_type in ["platlib", "purelib"]:
+                        path = sysconfig.get_path(path_type, scheme)
+                        try:
+                            if samefile(path, location):
+                                return sysconfig.get_path(name, scheme)
+                        except EnvironmentError:
+                            pass
+
+            data_path = get_sys_path(dist, "data") or sys.prefix
+            include_dir = os.path.join(data_path, "include", "pycairo")
+            ext.include_dirs += [include_dir]
+
         gi_ext = ext["gi._gi"]
         add_dependency(gi_ext, "glib-2.0")
         add_dependency(gi_ext, "gio-2.0")
@@ -287,7 +315,7 @@ class build_ext(du_build_ext):
         add_dependency(gi_cairo_ext, "libffi")
         add_dependency(gi_cairo_ext, "cairo")
         add_dependency(gi_cairo_ext, "cairo-gobject")
-        add_dependency(gi_cairo_ext, get_pycairo_pkg_config_name())
+        add_pycairo(gi_cairo_ext)
 
     def run(self):
         self._write_config_h()
@@ -308,6 +336,10 @@ def main():
     for s in cairo_sources:
         sources.remove(s)
 
+    readme = os.path.join(script_dir, "README.rst")
+    with io.open(readme, encoding="utf-8") as h:
+        long_description = h.read()
+
     gi_ext = Extension(
         name='gi._gi',
         sources=sources,
@@ -332,8 +364,7 @@ def main():
         maintainer=pkginfo["Maintainer"],
         maintainer_email=pkginfo["Maintainer-email"],
         license=pkginfo["License"],
-        download_url=pkginfo["Download-url"],
-        long_description=pkginfo["Description"],
+        long_description=long_description,
         platforms=pkginfo.get_all("Platform"),
         classifiers=pkginfo.get_all("Classifier"),
         packages=find_packages(script_dir),