PATCH: use GCC hidden visibility attribute

"James Henstridge" <[email protected]>
Newsgroups gmane.comp.python.db.psycopg.devel
Message-ID <[email protected]>
Attached is a patch that makes psycopg use GCC's "hidden" visibility
attribute on a bunch of symbols (provided it is compiled with GCC >=
4.0).

This does two things:
1. removes those symbols from the dynamic linking symbol table
2. simplifies references to those symbols inside _psycopg.so, since
they no longer have to go through the GOT.

On my AMD64 box, here are before and after results from "size":

   text    data     bss     dec     hex filename
 136450   16328     480  153258   256aa _psycopg.so

   text    data     bss     dec     hex filename
 128882   15856     480  145218   23742 _psycopg.so

Which is about a 5% reduction in code size.

James.

_______________________________________________
Psycopg mailing list
Psycopg-IAPFreCvJWPBWskQ1e/[email protected]
http://lists.initd.org/mailman/listinfo/psycopg
gcc-visibility.patch (text/x-patch, 20.1 KB)
Index: psycopg/adapter_datetime.h
===================================================================
--- psycopg/adapter_datetime.h	(revision 929)
+++ psycopg/adapter_datetime.h	(working copy)
@@ -25,11 +25,13 @@
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
 
+#include "psycopg/config.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-extern PyTypeObject pydatetimeType;
+extern HIDDEN PyTypeObject pydatetimeType;
 
 typedef struct {
     PyObject_HEAD
@@ -47,36 +49,36 @@
 /* functions exported to psycopgmodule.c */
 #ifdef PSYCOPG_DEFAULT_PYDATETIME
 
-extern PyObject *psyco_Date(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_Date(PyObject *module, PyObject *args);
 #define psyco_Date_doc \
     "Date(year, month, day) -> new date\n\n" \
     "Build an object holding a date value."
 
-extern PyObject *psyco_Time(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_Time(PyObject *module, PyObject *args);
 #define psyco_Time_doc \
     "Time(hour, minutes, seconds, tzinfo=None) -> new time\n\n" \
     "Build an object holding a time value."
 
-extern PyObject *psyco_Timestamp(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_Timestamp(PyObject *module, PyObject *args);
 #define psyco_Timestamp_doc \
     "Timestamp(year, month, day, hour, minutes, seconds, tzinfo=None) -> new timestamp\n\n" \
     "Build an object holding a timestamp value."
 
-extern PyObject *psyco_DateFromTicks(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_DateFromTicks(PyObject *module, PyObject *args);
 #define psyco_DateFromTicks_doc \
     "DateFromTicks(ticks) -> new date\n\n" \
     "Build an object holding a date value from the given ticks value.\n\n" \
     "Ticks are the number of seconds since the epoch; see the documentation " \
     "of the standard Python time module for details)."
 
-extern PyObject *psyco_TimeFromTicks(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_TimeFromTicks(PyObject *module, PyObject *args);
 #define psyco_TimeFromTicks_doc \
     "TimeFromTicks(ticks) -> new time\n\n" \
     "Build an object holding a time value from the given ticks value.\n\n" \
     "Ticks are the number of seconds since the epoch; see the documentation " \
     "of the standard Python time module for details)."
 
-extern PyObject *psyco_TimestampFromTicks(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_TimestampFromTicks(PyObject *module, PyObject *args);
 #define psyco_TimestampFromTicks_doc \
     "TimestampFromTicks(ticks) -> new timestamp\n\n" \
     "Build an object holding a timestamp value from the given ticks value.\n\n" \
@@ -85,19 +87,19 @@
 
 #endif /* PSYCOPG_DEFAULT_PYDATETIME */
 
-extern PyObject *psyco_DateFromPy(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_DateFromPy(PyObject *module, PyObject *args);
 #define psyco_DateFromPy_doc \
     "DateFromPy(datetime.date) -> new wrapper"
 
-extern PyObject *psyco_TimeFromPy(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_TimeFromPy(PyObject *module, PyObject *args);
 #define psyco_TimeFromPy_doc \
     "TimeFromPy(datetime.time) -> new wrapper"
 
-extern PyObject *psyco_TimestampFromPy(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_TimestampFromPy(PyObject *module, PyObject *args);
 #define psyco_TimestampFromPy_doc \
     "TimestampFromPy(datetime.datetime) -> new wrapper"
 
-extern PyObject *psyco_IntervalFromPy(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_IntervalFromPy(PyObject *module, PyObject *args);
 #define psyco_IntervalFromPy_doc \
     "IntervalFromPy(datetime.timedelta) -> new wrapper"
 
Index: psycopg/typecast.h
===================================================================
--- psycopg/typecast.h	(revision 929)
+++ psycopg/typecast.h	(working copy)
@@ -25,6 +25,8 @@
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
 
+#include "psycopg/config.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -34,7 +36,7 @@
 
 /** typecast type **/
 
-extern PyTypeObject typecastType;
+extern HIDDEN PyTypeObject typecastType;
 
 typedef struct {
     PyObject_HEAD
@@ -59,28 +61,28 @@
 } typecastObject_initlist;
 
 /* the type dictionary, much faster to access it globally */
-extern PyObject *psyco_types;
-extern PyObject *psyco_binary_types;
+extern HIDDEN PyObject *psyco_types;
+extern HIDDEN PyObject *psyco_binary_types;
 
 /* the default casting objects, used when no other objects are available */
-extern PyObject *psyco_default_cast;
-extern PyObject *psyco_default_binary_cast;
+extern HIDDEN PyObject *psyco_default_cast;
+extern HIDDEN PyObject *psyco_default_binary_cast;
 
 /** exported functions **/
 
 /* used by module.c to init the type system and register types */
-extern int typecast_init(PyObject *dict);
-extern int typecast_add(PyObject *obj, PyObject *dict, int binary);
+HIDDEN int typecast_init(PyObject *dict);
+HIDDEN int typecast_add(PyObject *obj, PyObject *dict, int binary);
 
 /* the C callable typecastObject creator function */
-extern PyObject *typecast_from_c(typecastObject_initlist *type, PyObject *d);
+HIDDEN PyObject *typecast_from_c(typecastObject_initlist *type, PyObject *d);
 
 /* the python callable typecast creator function */
-extern PyObject *typecast_from_python(
+HIDDEN PyObject *typecast_from_python(
     PyObject *self, PyObject *args, PyObject *keywds);
 
 /* the function used to dispatch typecasting calls */
-extern PyObject *typecast_cast(
+HIDDEN PyObject *typecast_cast(
     PyObject *self, char *str, Py_ssize_t len, PyObject *curs);
 
 #endif /* !defined(PSYCOPG_TYPECAST_H) */
Index: psycopg/adapter_asis.h
===================================================================
--- psycopg/adapter_asis.h	(revision 929)
+++ psycopg/adapter_asis.h	(working copy)
@@ -25,11 +25,13 @@
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
 
+#include "psycopg/config.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-extern PyTypeObject asisType;
+extern HIDDEN PyTypeObject asisType;
 
 typedef struct {
     PyObject_HEAD
@@ -41,7 +43,7 @@
 
 /* functions exported to psycopgmodule.c */
 
-extern PyObject *psyco_AsIs(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_AsIs(PyObject *module, PyObject *args);
 #define psyco_AsIs_doc \
     "AsIs(obj) -> new AsIs wrapper object"
 
Index: psycopg/typecast_binary.h
===================================================================
--- psycopg/typecast_binary.h	(revision 929)
+++ psycopg/typecast_binary.h	(working copy)
@@ -25,13 +25,15 @@
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
 
+#include "psycopg/config.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /** chunk type **/
 
-extern PyTypeObject chunkType;
+extern HIDDEN PyTypeObject chunkType;
 
 typedef struct {
     PyObject_HEAD
Index: psycopg/microprotocols_proto.h
===================================================================
--- psycopg/microprotocols_proto.h	(revision 929)
+++ psycopg/microprotocols_proto.h	(working copy)
@@ -26,11 +26,13 @@
 #include <Python.h>
 #include <libpq-fe.h>
 
+#include "psycopg/config.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-extern PyTypeObject isqlquoteType;
+extern HIDDEN PyTypeObject isqlquoteType;
 
 typedef struct {
     PyObject_HEAD
Index: psycopg/adapter_mxdatetime.h
===================================================================
--- psycopg/adapter_mxdatetime.h	(revision 929)
+++ psycopg/adapter_mxdatetime.h	(working copy)
@@ -25,11 +25,13 @@
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
 
+#include "psycopg/config.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-extern PyTypeObject mxdatetimeType;
+extern HIDDEN PyTypeObject mxdatetimeType;
 
 typedef struct {
     PyObject_HEAD
@@ -46,45 +48,45 @@
 /* functions exported to psycopgmodule.c */
 #ifdef PSYCOPG_DEFAULT_MXDATETIME
 
-extern PyObject *psyco_Date(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_Date(PyObject *module, PyObject *args);
 #define psyco_Date_doc \
     "Date(year, month, day) -> new date"
 
-extern PyObject *psyco_Time(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_Time(PyObject *module, PyObject *args);
 #define psyco_Time_doc \
     "Time(hour, minutes, seconds) -> new time"
 
-extern PyObject *psyco_Timestamp(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_Timestamp(PyObject *module, PyObject *args);
 #define psyco_Timestamp_doc \
     "Time(year, month, day, hour, minutes, seconds) -> new timestamp"
 
-extern PyObject *psyco_DateFromTicks(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_DateFromTicks(PyObject *module, PyObject *args);
 #define psyco_DateFromTicks_doc \
     "DateFromTicks(ticks) -> new date"
 
-extern PyObject *psyco_TimeFromTicks(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_TimeFromTicks(PyObject *module, PyObject *args);
 #define psyco_TimeFromTicks_doc \
     "TimeFromTicks(ticks) -> new time"
 
-extern PyObject *psyco_TimestampFromTicks(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_TimestampFromTicks(PyObject *module, PyObject *args);
 #define psyco_TimestampFromTicks_doc \
     "TimestampFromTicks(ticks) -> new timestamp"
 
 #endif /* PSYCOPG_DEFAULT_MXDATETIME */
 
-extern PyObject *psyco_DateFromMx(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_DateFromMx(PyObject *module, PyObject *args);
 #define psyco_DateFromMx_doc \
     "DateFromMx(mx) -> new date"
 
-extern PyObject *psyco_TimeFromMx(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_TimeFromMx(PyObject *module, PyObject *args);
 #define psyco_TimeFromMx_doc \
     "TimeFromMx(mx) -> new time"
 
-extern PyObject *psyco_TimestampFromMx(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_TimestampFromMx(PyObject *module, PyObject *args);
 #define psyco_TimestampFromMx_doc \
     "TimestampFromMx(mx) -> new timestamp"
 
-extern PyObject *psyco_IntervalFromMx(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_IntervalFromMx(PyObject *module, PyObject *args);
 #define psyco_IntervalFromMx_doc \
     "IntervalFromMx(mx) -> new interval"
 
Index: psycopg/config.h
===================================================================
--- psycopg/config.h	(revision 929)
+++ psycopg/config.h	(working copy)
@@ -22,9 +22,16 @@
 #ifndef PSYCOPG_CONFIG_H
 #define PSYCOPG_CONFIG_H 1
 
+/* GCC 4.0 and later have support for specifying symbol visibility */
+#if __GNUC__ >= 4
+#  define HIDDEN __attribute__((visibility("hidden")))
+#else
+#  define HIDDEN
+#endif
+
 /* debug printf-like function */
 #ifdef PSYCOPG_DEBUG
-extern int psycopg_debug_enabled;
+extern HIDDEN int psycopg_debug_enabled;
 #endif
 
 #if defined( __GNUC__) && !defined(__APPLE__)
Index: psycopg/microprotocols.h
===================================================================
--- psycopg/microprotocols.h	(revision 929)
+++ psycopg/microprotocols.h	(working copy)
@@ -24,6 +24,7 @@
 
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
+#include "psycopg/config.h"
 #include "psycopg/connection.h"
 #include "psycopg/cursor.h"
 
@@ -33,7 +34,7 @@
 
 /** adapters registry **/
 
-extern PyObject *psyco_adapters;
+extern HIDDEN PyObject *psyco_adapters;
 
 /** the names of the three mandatory methods **/
 
@@ -44,16 +45,16 @@
 /** exported functions **/
 
 /* used by module.c to init the microprotocols system */
-extern int microprotocols_init(PyObject *dict);
-extern int microprotocols_add(
+HIDDEN int microprotocols_init(PyObject *dict);
+HIDDEN int microprotocols_add(
     PyTypeObject *type, PyObject *proto, PyObject *cast);
 
-extern PyObject *microprotocols_adapt(
+HIDDEN PyObject *microprotocols_adapt(
     PyObject *obj, PyObject *proto, PyObject *alt);
-extern PyObject *microprotocol_getquoted(
+HIDDEN PyObject *microprotocol_getquoted(
     PyObject *obj, connectionObject *conn);
 
-extern PyObject *
+HIDDEN PyObject *
     psyco_microprotocols_adapt(cursorObject *self, PyObject *args);
 #define psyco_microprotocols_adapt_doc \
     "adapt(obj, protocol, alternate) -> object -- adapt obj to given protocol"
Index: psycopg/adapter_binary.h
===================================================================
--- psycopg/adapter_binary.h	(revision 929)
+++ psycopg/adapter_binary.h	(working copy)
@@ -26,11 +26,13 @@
 #include <Python.h>
 #include <libpq-fe.h>
 
+#include "psycopg/config.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-extern PyTypeObject binaryType;
+extern HIDDEN PyTypeObject binaryType;
 
 typedef struct {
     PyObject_HEAD
@@ -42,7 +44,7 @@
 
 /* functions exported to psycopgmodule.c */
 
-extern PyObject *psyco_Binary(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_Binary(PyObject *module, PyObject *args);
 #define psyco_Binary_doc \
     "Binary(buffer) -> new binary object\n\n" \
     "Build an object capable to hold a bynary string value."
Index: psycopg/psycopg.h
===================================================================
--- psycopg/psycopg.h	(revision 929)
+++ psycopg/psycopg.h	(working copy)
@@ -25,6 +25,8 @@
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
 
+#include "psycopg/config.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -77,12 +79,13 @@
 #define PSYCOPG_API_pointers 2
 
 #ifdef PSYCOPG_MODULE
+
     /** This section is used when compiling psycopgmodule.c & co. **/
-extern psyco_errors_fill_RETURN psyco_errors_fill psyco_errors_fill_PROTO;
-extern psyco_errors_set_RETURN psyco_errors_set psyco_errors_set_PROTO;
+HIDDEN psyco_errors_fill_RETURN psyco_errors_fill psyco_errors_fill_PROTO;
+HIDDEN psyco_errors_set_RETURN psyco_errors_set psyco_errors_set_PROTO;
 
 /* global excpetions */
-extern PyObject *Error, *Warning, *InterfaceError, *DatabaseError,
+extern HIDDEN PyObject *Error, *Warning, *InterfaceError, *DatabaseError,
     *InternalError, *OperationalError, *ProgrammingError,
     *IntegrityError, *DataError, *NotSupportedError;
 #ifdef PSYCOPG_EXTENSIONS
@@ -125,7 +128,7 @@
 #endif
 
 /* postgresql<->python encoding map */
-extern PyObject *psycoEncodings;
+extern HIDDEN PyObject *psycoEncodings;
 
 typedef struct {
     char *pgenc;
@@ -133,10 +136,10 @@
 } encodingPair;
 
 /* the Decimal type, used by the DECIMAL typecaster */
-extern PyObject *psyco_GetDecimalType(void);
+HIDDEN PyObject *psyco_GetDecimalType(void);
 
 /* some utility functions */
-extern void psyco_set_error(PyObject *exc, PyObject *curs,  const char *msg,
+HIDDEN void psyco_set_error(PyObject *exc, PyObject *curs,  const char *msg,
                             const char *pgerror, const char *pgcode);
 
 /* Exceptions docstrings */
Index: psycopg/pqpath.h
===================================================================
--- psycopg/pqpath.h	(revision 929)
+++ psycopg/pqpath.h	(working copy)
@@ -22,6 +22,7 @@
 #ifndef PSYCOPG_PQPATH_H
 #define PSYCOPG_PQPATH_H 1
 
+#include "psycopg/config.h"
 #include "psycopg/cursor.h"
 #include "psycopg/connection.h"
 
@@ -30,20 +31,20 @@
 #define CLEARPGRES(pgres)    PQclear(pgres); pgres = NULL
 
 /* exported functions */
-extern int pq_fetch(cursorObject *curs);
-extern int pq_execute(cursorObject *curs, const char *query, int async);
-extern int pq_commit(connectionObject *conn);
-extern int pq_abort_locked(connectionObject *conn, PGresult **pgres,
+HIDDEN int pq_fetch(cursorObject *curs);
+HIDDEN int pq_execute(cursorObject *curs, const char *query, int async);
+HIDDEN int pq_commit(connectionObject *conn);
+HIDDEN int pq_abort_locked(connectionObject *conn, PGresult **pgres,
                            char **error);
-extern int pq_abort(connectionObject *conn);
-extern int pq_is_busy(connectionObject *conn);
+HIDDEN int pq_abort(connectionObject *conn);
+HIDDEN int pq_is_busy(connectionObject *conn);
 
-extern void pq_set_critical(connectionObject *conn, const char *msg);
+HIDDEN void pq_set_critical(connectionObject *conn, const char *msg);
 
-extern int pq_execute_command_locked(connectionObject *conn,
+HIDDEN int pq_execute_command_locked(connectionObject *conn,
                                      const char *query,
                                      PGresult **pgres, char **error);
-extern void pq_complete_error(connectionObject *conn, PGresult **pgres,
+HIDDEN void pq_complete_error(connectionObject *conn, PGresult **pgres,
                               char **error);
 
 #endif /* !defined(PSYCOPG_PQPATH_H) */
Index: psycopg/connection.h
===================================================================
--- psycopg/connection.h	(revision 929)
+++ psycopg/connection.h	(working copy)
@@ -26,6 +26,8 @@
 #include <Python.h>
 #include <libpq-fe.h>
 
+#include "psycopg/config.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -39,7 +41,7 @@
 /* Hard limit on the notices stored by the Python connection */
 #define CONN_NOTICES_LIMIT 50
 
-extern PyTypeObject connectionType;
+extern HIDDEN PyTypeObject connectionType;
 
 typedef struct {
     PyObject_HEAD
@@ -76,12 +78,12 @@
 } connectionObject;
 
 /* C-callable functions in connection_int.c and connection_ext.c */
-extern int  conn_connect(connectionObject *self);
-extern void conn_close(connectionObject *self);
-extern int  conn_commit(connectionObject *self);
-extern int  conn_rollback(connectionObject *self);
-extern int  conn_switch_isolation_level(connectionObject *self, int level);
-extern int  conn_set_client_encoding(connectionObject *self, char *enc);
+HIDDEN int  conn_connect(connectionObject *self);
+HIDDEN void conn_close(connectionObject *self);
+HIDDEN int  conn_commit(connectionObject *self);
+HIDDEN int  conn_rollback(connectionObject *self);
+HIDDEN int  conn_switch_isolation_level(connectionObject *self, int level);
+HIDDEN int  conn_set_client_encoding(connectionObject *self, char *enc);
 
 /* exception-raising macros */
 #define EXC_IF_CONN_CLOSED(self) if ((self)->closed > 0) { \
Index: psycopg/adapter_pboolean.h
===================================================================
--- psycopg/adapter_pboolean.h	(revision 929)
+++ psycopg/adapter_pboolean.h	(working copy)
@@ -25,11 +25,13 @@
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
 
+#include "psycopg/config.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-extern PyTypeObject pbooleanType;
+extern HIDDEN PyTypeObject pbooleanType;
 
 typedef struct {
     PyObject_HEAD
@@ -41,7 +43,7 @@
 
 /* functions exported to psycopgmodule.c */
 
-extern PyObject *psyco_Boolean(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_Boolean(PyObject *module, PyObject *args);
 #define psyco_Boolean_doc \
     "Boolean(obj) -> new boolean value"
 
Index: psycopg/adapter_list.h
===================================================================
--- psycopg/adapter_list.h	(revision 929)
+++ psycopg/adapter_list.h	(working copy)
@@ -25,11 +25,13 @@
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
 
+#include "psycopg/config.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-extern PyTypeObject listType;
+extern HIDDEN PyTypeObject listType;
 
 typedef struct {
     PyObject_HEAD
@@ -39,7 +41,7 @@
     char     *encoding;
 } listObject;
 
-extern PyObject *psyco_List(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_List(PyObject *module, PyObject *args);
 #define psyco_List_doc \
     "List(list, enc) -> new quoted list"
 
Index: psycopg/cursor.h
===================================================================
--- psycopg/cursor.h	(revision 929)
+++ psycopg/cursor.h	(working copy)
@@ -26,13 +26,14 @@
 #include <Python.h>
 #include <libpq-fe.h>
 
+#include "psycopg/config.h"
 #include "psycopg/connection.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-extern PyTypeObject cursorType;
+extern HIDDEN PyTypeObject cursorType;
 
 typedef struct {
     PyObject_HEAD
@@ -80,7 +81,7 @@
 } cursorObject;
 
 /* C-callable functions in cursor_int.c and cursor_ext.c */
-extern void curs_reset(cursorObject *self);
+HIDDEN void curs_reset(cursorObject *self);
 
 /* exception-raising macros */
 #define EXC_IF_CURS_CLOSED(self) \
Index: psycopg/adapter_qstring.h
===================================================================
--- psycopg/adapter_qstring.h	(revision 929)
+++ psycopg/adapter_qstring.h	(working copy)
@@ -25,11 +25,13 @@
 #define PY_SSIZE_T_CLEAN
 #include <Python.h>
 
+#include "psycopg/config.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-extern PyTypeObject qstringType;
+extern HIDDEN PyTypeObject qstringType;
 
 typedef struct {
     PyObject_HEAD
@@ -43,7 +45,7 @@
 
 /* functions exported to psycopgmodule.c */
 
-extern PyObject *psyco_QuotedString(PyObject *module, PyObject *args);
+HIDDEN PyObject *psyco_QuotedString(PyObject *module, PyObject *args);
 #define psyco_QuotedString_doc \
     "QuotedString(str, enc) -> new quoted string"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.